diff --git a/.coveragerc b/.coveragerc
index 9b0751055..f12d4dc21 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -18,11 +18,11 @@
[run]
branch = True
omit =
- google/cloud/__init__.py
- google/__init__.py
+ google/cloud/bigtable_admin/__init__.py
+ google/cloud/bigtable_admin/gapic_version.py
[report]
-fail_under = 100
+fail_under = 99
show_missing = True
exclude_lines =
# Re-enable the standard pragma
@@ -31,11 +31,5 @@ exclude_lines =
def __repr__
# Ignore abstract methods
raise NotImplementedError
- # Ignore setuptools-less fallback
- except pkg_resources.DistributionNotFound:
omit =
- */gapic/*.py
- */proto/*.py
- */core/*.py
*/site-packages/*.py
- google/cloud/__init__.py
diff --git a/.cross_sync/README.md b/.cross_sync/README.md
new file mode 100644
index 000000000..0d8a1cf8c
--- /dev/null
+++ b/.cross_sync/README.md
@@ -0,0 +1,75 @@
+# CrossSync
+
+CrossSync provides a simple way to share logic between async and sync code.
+It is made up of a small library that provides:
+1. a set of shims that provide a shared sync/async API surface
+2. annotations that are used to guide generation of a sync version from an async class
+
+Using CrossSync, the async code is treated as the source of truth, and sync code is generated from it.
+
+## Usage
+
+### CrossSync Shims
+
+Many Asyncio components have direct, 1:1 threaded counterparts for use in non-asyncio code. CrossSync
+provides a compatibility layer that works with both
+
+| CrossSync | Asyncio Version | Sync Version |
+| --- | --- | --- |
+| CrossSync.Queue | asyncio.Queue | queue.Queue |
+| CrossSync.Condition | asyncio.Condition | threading.Condition |
+| CrossSync.Future | asyncio.Future | Concurrent.futures.Future |
+| CrossSync.Task | asyncio.Task | Concurrent.futures.Future |
+| CrossSync.Event | asyncio.Event | threading.Event |
+| CrossSync.Semaphore | asyncio.Semaphore | threading.Semaphore |
+| CrossSync.Awaitable | typing.Awaitable | typing.Union (no-op type) |
+| CrossSync.Iterable | typing.AsyncIterable | typing.Iterable |
+| CrossSync.Iterator | typing.AsyncIterator | typing.Iterator |
+| CrossSync.Generator | typing.AsyncGenerator | typing.Generator |
+| CrossSync.Retry | google.api_core.retry.AsyncRetry | google.api_core.retry.Retry |
+| CrossSync.StopIteration | StopAsyncIteration | StopIteration |
+| CrossSync.Mock | unittest.mock.AsyncMock | unittest.mock.Mock |
+
+Custom aliases can be added using `CrossSync.add_mapping(class, name)`
+
+Additionally, CrossSync provides method implementations that work equivalently in async and sync code:
+- `CrossSync.sleep()`
+- `CrossSync.gather_partials()`
+- `CrossSync.wait()`
+- `CrossSync.condition_wait()`
+- `CrossSync,event_wait()`
+- `CrossSync.create_task()`
+- `CrossSync.retry_target()`
+- `CrossSync.retry_target_stream()`
+
+### Annotations
+
+CrossSync provides a set of annotations to mark up async classes, to guide the generation of sync code.
+
+- `@CrossSync.convert_sync`
+ - marks classes for conversion. Unmarked classes will be copied as-is
+ - if add_mapping is included, the async and sync classes can be accessed using a shared CrossSync.X alias
+- `@CrossSync.convert`
+ - marks async functions for conversion. Unmarked methods will be copied as-is
+- `@CrossSync.drop`
+ - marks functions or classes that should not be included in sync output
+- `@CrossSync.pytest`
+ - marks test functions. Test functions automatically have all async keywords stripped (i.e., rm_aio is unneeded)
+- `CrossSync.add_mapping`
+ - manually registers a new CrossSync.X alias, for custom types
+- `CrossSync.rm_aio`
+ - Marks regions of the code that include asyncio keywords that should be stripped during generation
+
+### Code Generation
+
+Generation can be initiated using `nox -s generate_sync`
+from the root of the project. This will find all classes with the `__CROSS_SYNC_OUTPUT__ = "path/to/output"`
+annotation, and generate a sync version of classes marked with `@CrossSync.convert_sync` at the output path.
+
+There is a unit test at `tests/unit/data/test_sync_up_to_date.py` that verifies that the generated code is up to date
+
+## Architecture
+
+CrossSync is made up of two parts:
+- the runtime shims and annotations live in `/google/cloud/bigtable/_cross_sync`
+- the code generation logic lives in `/.cross_sync/` in the repo root
diff --git a/.cross_sync/generate.py b/.cross_sync/generate.py
new file mode 100644
index 000000000..5158d0f37
--- /dev/null
+++ b/.cross_sync/generate.py
@@ -0,0 +1,107 @@
+# Copyright 2024 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.
+from __future__ import annotations
+from typing import Sequence
+import ast
+"""
+Entrypoint for initiating an async -> sync conversion using CrossSync
+
+Finds all python files rooted in a given directory, and uses
+transformers.CrossSyncFileProcessor to handle any files marked with
+__CROSS_SYNC_OUTPUT__
+"""
+
+
+def extract_header_comments(file_path) -> str:
+ """
+ Extract the file header. Header is defined as the top-level
+ comments before any code or imports
+ """
+ header = []
+ with open(file_path, "r") as f:
+ for line in f:
+ if line.startswith("#") or line.strip() == "":
+ header.append(line)
+ else:
+ break
+ header.append("\n# This file is automatically generated by CrossSync. Do not edit manually.\n\n")
+ return "".join(header)
+
+
+class CrossSyncOutputFile:
+
+ def __init__(self, output_path: str, ast_tree, header: str | None = None):
+ self.output_path = output_path
+ self.tree = ast_tree
+ self.header = header or ""
+
+ def render(self, with_formatter=True, save_to_disk: bool = True) -> str:
+ """
+ Render the file to a string, and optionally save to disk
+
+ Args:
+ with_formatter: whether to run the output through black before returning
+ save_to_disk: whether to write the output to the file path
+ """
+ full_str = self.header + ast.unparse(self.tree)
+ if with_formatter:
+ import black # type: ignore
+ import autoflake # type: ignore
+
+ full_str = black.format_str(
+ autoflake.fix_code(full_str, remove_all_unused_imports=True),
+ mode=black.FileMode(),
+ )
+ if save_to_disk:
+ import os
+ os.makedirs(os.path.dirname(self.output_path), exist_ok=True)
+ with open(self.output_path, "w") as f:
+ f.write(full_str)
+ return full_str
+
+
+def convert_files_in_dir(directory: str) -> set[CrossSyncOutputFile]:
+ import glob
+ from transformers import CrossSyncFileProcessor
+
+ # find all python files in the directory
+ files = glob.glob(directory + "/**/*.py", recursive=True)
+ # keep track of the output files pointed to by the annotated classes
+ artifacts: set[CrossSyncOutputFile] = set()
+ file_transformer = CrossSyncFileProcessor()
+ # run each file through ast transformation to find all annotated classes
+ for file_path in files:
+ ast_tree = ast.parse(open(file_path).read())
+ output_path = file_transformer.get_output_path(ast_tree)
+ if output_path is not None:
+ # contains __CROSS_SYNC_OUTPUT__ annotation
+ converted_tree = file_transformer.visit(ast_tree)
+ header = extract_header_comments(file_path)
+ artifacts.add(CrossSyncOutputFile(output_path, converted_tree, header))
+ # return set of output artifacts
+ return artifacts
+
+
+def save_artifacts(artifacts: Sequence[CrossSyncOutputFile]):
+ for a in artifacts:
+ a.render(save_to_disk=True)
+
+
+if __name__ == "__main__":
+ import sys
+
+ search_root = sys.argv[1]
+ outputs = convert_files_in_dir(search_root)
+ print(f"Generated {len(outputs)} artifacts: {[a.output_path for a in outputs]}")
+ save_artifacts(outputs)
diff --git a/.cross_sync/transformers.py b/.cross_sync/transformers.py
new file mode 100644
index 000000000..9adadd0aa
--- /dev/null
+++ b/.cross_sync/transformers.py
@@ -0,0 +1,338 @@
+# Copyright 2024 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.
+"""
+Provides a set of ast.NodeTransformer subclasses that are composed to generate
+async code into sync code.
+
+At a high level:
+- The main entrypoint is CrossSyncFileProcessor, which is used to find files in
+ the codebase that include __CROSS_SYNC_OUTPUT__, and transform them
+ according to the `CrossSync` annotations they contains
+- SymbolReplacer is used to swap out CrossSync.X with CrossSync._Sync_Impl.X
+- RmAioFunctions is used to strip out asyncio keywords marked with CrossSync.rm_aio
+ (deferring to AsyncToSync to handle the actual transformation)
+- StripAsyncConditionalBranches finds `if CrossSync.is_async:` conditionals, and strips out
+ the unneeded branch for the sync output
+"""
+from __future__ import annotations
+
+import ast
+
+import sys
+# add cross_sync to path
+sys.path.append("google/cloud/bigtable/data/_cross_sync")
+from _decorators import AstDecorator
+
+
+class SymbolReplacer(ast.NodeTransformer):
+ """
+ Replaces all instances of a symbol in an AST with a replacement
+
+ Works for function signatures, method calls, docstrings, and type annotations
+ """
+ def __init__(self, replacements: dict[str, str]):
+ self.replacements = replacements
+
+ def visit_Name(self, node):
+ if node.id in self.replacements:
+ node.id = self.replacements[node.id]
+ return node
+
+ def visit_Attribute(self, node):
+ return ast.copy_location(
+ ast.Attribute(
+ self.visit(node.value),
+ self.replacements.get(node.attr, node.attr),
+ node.ctx,
+ ),
+ node,
+ )
+
+ def visit_AsyncFunctionDef(self, node):
+ """
+ Replace async function docstrings
+ """
+ # use same logic as FunctionDef
+ return self.visit_FunctionDef(node)
+
+ def visit_FunctionDef(self, node):
+ """
+ Replace function docstrings
+ """
+ docstring = ast.get_docstring(node)
+ if docstring and isinstance(node.body[0], ast.Expr) \
+ and isinstance(node.body[0].value, ast.Constant) \
+ and isinstance(node.body[0].value.value, str) \
+ :
+ for key_word, replacement in self.replacements.items():
+ docstring = docstring.replace(key_word, replacement)
+ node.body[0].value.value = docstring
+ return self.generic_visit(node)
+
+ def visit_Constant(self, node):
+ """Replace string type annotations"""
+ try:
+ node.value = self.replacements.get(node.value, node.value)
+ except TypeError:
+ # ignore unhashable types (e.g. list)
+ pass
+ return node
+
+
+class AsyncToSync(ast.NodeTransformer):
+ """
+ Replaces or strips all async keywords from a given AST
+ """
+ def visit_Await(self, node):
+ """
+ Strips await keyword
+ """
+ return self.visit(node.value)
+
+ def visit_AsyncFor(self, node):
+ """
+ Replaces `async for` with `for`
+ """
+ return ast.copy_location(
+ ast.For(
+ self.visit(node.target),
+ self.visit(node.iter),
+ [self.visit(stmt) for stmt in node.body],
+ [self.visit(stmt) for stmt in node.orelse],
+ ),
+ node,
+ )
+
+ def visit_AsyncWith(self, node):
+ """
+ Replaces `async with` with `with`
+ """
+ return ast.copy_location(
+ ast.With(
+ [self.visit(item) for item in node.items],
+ [self.visit(stmt) for stmt in node.body],
+ ),
+ node,
+ )
+
+ def visit_AsyncFunctionDef(self, node):
+ """
+ Replaces `async def` with `def`
+ """
+ return ast.copy_location(
+ ast.FunctionDef(
+ node.name,
+ self.visit(node.args),
+ [self.visit(stmt) for stmt in node.body],
+ [self.visit(decorator) for decorator in node.decorator_list],
+ node.returns and self.visit(node.returns),
+ ),
+ node,
+ )
+
+ def visit_ListComp(self, node):
+ """
+ Replaces `async for` with `for` in list comprehensions
+ """
+ for generator in node.generators:
+ generator.is_async = False
+ return self.generic_visit(node)
+
+
+class RmAioFunctions(ast.NodeTransformer):
+ """
+ Visits all calls marked with CrossSync.rm_aio, and removes asyncio keywords
+ """
+ RM_AIO_FN_NAME = "rm_aio"
+ RM_AIO_CLASS_NAME = "CrossSync"
+
+ def __init__(self):
+ self.to_sync = AsyncToSync()
+
+ def _is_rm_aio_call(self, node) -> bool:
+ """
+ Check if a node is a CrossSync.rm_aio call
+ """
+ if isinstance(node, ast.Call) and isinstance(node.func, ast.Attribute) and isinstance(node.func.value, ast.Name):
+ if node.func.attr == self.RM_AIO_FN_NAME and node.func.value.id == self.RM_AIO_CLASS_NAME:
+ return True
+ return False
+
+ def visit_Call(self, node):
+ if self._is_rm_aio_call(node):
+ return self.visit(self.to_sync.visit(node.args[0]))
+ return self.generic_visit(node)
+
+ def visit_AsyncWith(self, node):
+ """
+ `async with` statements can contain multiple async context managers.
+
+ If any of them contains a CrossSync.rm_aio statement, convert into standard `with` statement
+ """
+ if any(self._is_rm_aio_call(item.context_expr) for item in node.items
+ ):
+ new_node = ast.copy_location(
+ ast.With(
+ [self.visit(item) for item in node.items],
+ [self.visit(stmt) for stmt in node.body],
+ ),
+ node,
+ )
+ return self.generic_visit(new_node)
+ return self.generic_visit(node)
+
+ def visit_AsyncFor(self, node):
+ """
+ Async for statements are not fully wrapped by calls
+ """
+ it = node.iter
+ if self._is_rm_aio_call(it):
+ return ast.copy_location(
+ ast.For(
+ self.visit(node.target),
+ self.visit(it),
+ [self.visit(stmt) for stmt in node.body],
+ [self.visit(stmt) for stmt in node.orelse],
+ ),
+ node,
+ )
+ return self.generic_visit(node)
+
+
+class StripAsyncConditionalBranches(ast.NodeTransformer):
+ """
+ Visits all if statements in an AST, and removes branches marked with CrossSync.is_async
+ """
+
+ def visit_If(self, node):
+ """
+ remove CrossSync.is_async branches from top-level if statements
+ """
+ kept_branch = None
+ # check for CrossSync.is_async
+ if self._is_async_check(node.test):
+ kept_branch = node.orelse
+ # check for not CrossSync.is_async
+ elif isinstance(node.test, ast.UnaryOp) and isinstance(node.test.op, ast.Not) and self._is_async_check(node.test.operand):
+ kept_branch = node.body
+ if kept_branch is not None:
+ # only keep the statements in the kept branch
+ return [self.visit(n) for n in kept_branch]
+ else:
+ # keep the entire if statement
+ return self.generic_visit(node)
+
+ def _is_async_check(self, node) -> bool:
+ """
+ Check for CrossSync.is_async or CrossSync.is_async == True checks
+ """
+ if isinstance(node, ast.Attribute):
+ # for CrossSync.is_async
+ return isinstance(node.value, ast.Name) and node.value.id == "CrossSync" and node.attr == "is_async"
+ elif isinstance(node, ast.Compare):
+ # for CrossSync.is_async == True
+ return self._is_async_check(node.left) and (isinstance(node.ops[0], ast.Eq) or isinstance(node.ops[0], ast.Is)) and len(node.comparators) == 1 and node.comparators[0].value == True
+ return False
+
+
+class CrossSyncFileProcessor(ast.NodeTransformer):
+ """
+ Visits a file, looking for __CROSS_SYNC_OUTPUT__ annotations
+
+ If found, the file is processed with the following steps:
+ - Strip out asyncio keywords within CrossSync.rm_aio calls
+ - transform classes and methods annotated with CrossSync decorators
+ - statements behind CrossSync.is_async conditional branches are removed
+ - Replace remaining CrossSync statements with corresponding CrossSync._Sync_Impl calls
+ - save changes in an output file at path specified by __CROSS_SYNC_OUTPUT__
+ """
+ FILE_ANNOTATION = "__CROSS_SYNC_OUTPUT__"
+
+ def get_output_path(self, node):
+ for n in node.body:
+ if isinstance(n, ast.Assign):
+ for target in n.targets:
+ if isinstance(target, ast.Name) and target.id == self.FILE_ANNOTATION:
+ # return the output path
+ return n.value.value.replace(".", "/") + ".py"
+
+ def visit_Module(self, node):
+ # look for __CROSS_SYNC_OUTPUT__ Assign statement
+ output_path = self.get_output_path(node)
+ if output_path:
+ # if found, process the file
+ converted = self.generic_visit(node)
+ # strip out CrossSync.rm_aio calls
+ converted = RmAioFunctions().visit(converted)
+ # strip out CrossSync.is_async branches
+ converted = StripAsyncConditionalBranches().visit(converted)
+ # replace CrossSync statements
+ converted = SymbolReplacer({"CrossSync": "CrossSync._Sync_Impl"}).visit(converted)
+ return converted
+ else:
+ # not cross_sync file. Return None
+ return None
+
+ def visit_ClassDef(self, node):
+ """
+ Called for each class in file. If class has a CrossSync decorator, it will be transformed
+ according to the decorator arguments. Otherwise, class is returned unchanged
+ """
+ orig_decorators = node.decorator_list
+ for decorator in orig_decorators:
+ try:
+ handler = AstDecorator.get_for_node(decorator)
+ # transformation is handled in sync_ast_transform method of the decorator
+ node = handler.sync_ast_transform(node, globals())
+ except ValueError:
+ # not cross_sync decorator
+ continue
+ return self.generic_visit(node) if node else None
+
+ def visit_Assign(self, node):
+ """
+ strip out __CROSS_SYNC_OUTPUT__ assignments
+ """
+ if isinstance(node.targets[0], ast.Name) and node.targets[0].id == self.FILE_ANNOTATION:
+ return None
+ return self.generic_visit(node)
+
+ def visit_FunctionDef(self, node):
+ """
+ Visit any sync methods marked with CrossSync decorators
+ """
+ return self.visit_AsyncFunctionDef(node)
+
+ def visit_AsyncFunctionDef(self, node):
+ """
+ Visit and transform any async methods marked with CrossSync decorators
+ """
+ try:
+ if hasattr(node, "decorator_list"):
+ found_list, node.decorator_list = node.decorator_list, []
+ for decorator in found_list:
+ try:
+ handler = AstDecorator.get_for_node(decorator)
+ node = handler.sync_ast_transform(node, globals())
+ if node is None:
+ return None
+ # recurse to any nested functions
+ node = self.generic_visit(node)
+ except ValueError:
+ # keep unknown decorators
+ node.decorator_list.append(decorator)
+ continue
+ return self.generic_visit(node)
+ except ValueError as e:
+ raise ValueError(f"node {node.name} failed") from e
diff --git a/.flake8 b/.flake8
index 2e4387498..32986c792 100644
--- a/.flake8
+++ b/.flake8
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
-# Copyright 2020 Google LLC
+# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 2f1fee904..4012444e4 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -5,8 +5,8 @@
# https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax
# Note: This file is autogenerated. To make changes to the codeowner team, please update .repo-metadata.json.
-# @googleapis/yoshi-python @googleapis/api-bigtable are the default owners for changes in this repo
-* @googleapis/yoshi-python @googleapis/api-bigtable
+# @googleapis/yoshi-python @googleapis/api-bigtable @googleapis/api-bigtable-partners are the default owners for changes in this repo
+* @googleapis/yoshi-python @googleapis/api-bigtable @googleapis/api-bigtable-partners
-# @googleapis/python-samples-reviewers @googleapis/api-bigtable are the default owners for samples changes
-/samples/ @googleapis/python-samples-reviewers @googleapis/api-bigtable
+# @googleapis/python-samples-reviewers @googleapis/api-bigtable @googleapis/api-bigtable-partners are the default owners for samples changes
+/samples/ @googleapis/python-samples-reviewers @googleapis/api-bigtable @googleapis/api-bigtable-partners @googleapis/cloud-sdk-python-team
diff --git a/.github/auto-approve.yml b/.github/auto-approve.yml
deleted file mode 100644
index 311ebbb85..000000000
--- a/.github/auto-approve.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-# https://github.com/googleapis/repo-automation-bots/tree/main/packages/auto-approve
-processes:
- - "OwlBotTemplateChanges"
diff --git a/.github/auto-label.yaml b/.github/auto-label.yaml
index 41bff0b53..21786a4eb 100644
--- a/.github/auto-label.yaml
+++ b/.github/auto-label.yaml
@@ -1,4 +1,4 @@
-# Copyright 2022 Google LLC
+# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -13,3 +13,8 @@
# limitations under the License.
requestsize:
enabled: true
+
+path:
+ pullrequest: true
+ paths:
+ samples: "samples"
diff --git a/.github/blunderbuss.yml b/.github/blunderbuss.yml
new file mode 100644
index 000000000..1e27e789a
--- /dev/null
+++ b/.github/blunderbuss.yml
@@ -0,0 +1,20 @@
+# Blunderbuss config
+#
+# This file controls who is assigned for pull requests and issues.
+# Note: This file is autogenerated. To make changes to the assignee
+# team, please update `codeowner_team` in `.repo-metadata.json`.
+assign_issues:
+ - googleapis/api-bigtable
+ - googleapis/api-bigtable-partners
+
+assign_issues_by:
+ - labels:
+ - "samples"
+ to:
+ - googleapis/python-samples-reviewers
+ - googleapis/api-bigtable
+ - googleapis/api-bigtable-partners
+
+assign_prs:
+ - googleapis/api-bigtable
+ - googleapis/api-bigtable-partners
diff --git a/.github/.OwlBot.lock.yaml b/.github/flakybot.yaml
similarity index 70%
rename from .github/.OwlBot.lock.yaml
rename to .github/flakybot.yaml
index 1ce608523..2159a1bca 100644
--- a/.github/.OwlBot.lock.yaml
+++ b/.github/flakybot.yaml
@@ -1,4 +1,4 @@
-# Copyright 2022 Google LLC
+# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -11,7 +11,5 @@
# 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.
-docker:
- image: gcr.io/cloud-devrel-public-resources/owlbot-python:latest
- digest: sha256:e7bb19d47c13839fe8c147e50e02e8b6cf5da8edd1af8b82208cd6f66cc2829c
-# created: 2022-07-05T18:31:20.838186805Z
+
+issuePriority: p2
\ No newline at end of file
diff --git a/.github/release-please.yml b/.github/release-please.yml
deleted file mode 100644
index 29601ad46..000000000
--- a/.github/release-please.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-releaseType: python
-handleGHRelease: true
-# NOTE: this section is generated by synthtool.languages.python
-# See https://github.com/googleapis/synthtool/blob/master/synthtool/languages/python.py
-branches:
-- branch: v1
- handleGHRelease: true
- releaseType: python
-- branch: v0
- handleGHRelease: true
- releaseType: python
diff --git a/.github/release-trigger.yml b/.github/release-trigger.yml
deleted file mode 100644
index d4ca94189..000000000
--- a/.github/release-trigger.yml
+++ /dev/null
@@ -1 +0,0 @@
-enabled: true
diff --git a/.github/sync-repo-settings.yaml b/.github/sync-repo-settings.yaml
deleted file mode 100644
index a0d3362c9..000000000
--- a/.github/sync-repo-settings.yaml
+++ /dev/null
@@ -1,47 +0,0 @@
-# Whether or not rebase-merging is enabled on this repository.
-# Defaults to `true`
-rebaseMergeAllowed: true
-
-# Whether or not squash-merging is enabled on this repository.
-# Defaults to `true`
-squashMergeAllowed: true
-
-# Whether or not PRs are merged with a merge commit on this repository.
-# Defaults to `false`
-mergeCommitAllowed: false
-
-# Rules for main branch protection
-branchProtectionRules:
-# Identifies the protection rule pattern. Name of the branch to be protected.
-# Defaults to `main`
-- pattern: main
- # Can admins overwrite branch protection.
- # Defaults to `true`
- isAdminEnforced: true
- # Number of approving reviews required to update matching branches.
- # Defaults to `1`
- requiredApprovingReviewCount: 1
- # Are reviews from code owners required to update matching branches.
- # Defaults to `false`
- requiresCodeOwnerReviews: true
- # Require up to date branches
- requiresStrictStatusChecks: false
- # List of required status check contexts that must pass for commits to be accepted to matching branches.
- requiredStatusCheckContexts:
- - 'Kokoro'
- - 'Kokoro system-3.8'
- - 'cla/google'
-# List of explicit permissions to add (additive only)
-permissionRules:
- # Team slug to add to repository permissions
- - team: yoshi-admins
- # Access level required, one of push|pull|admin|maintain|triage
- permission: admin
- # Team slug to add to repository permissions
- - team: yoshi-python-admins
- # Access level required, one of push|pull|admin|maintain|triage
- permission: admin
- # Team slug to add to repository permissions
- - team: yoshi-python
- # Access level required, one of push|pull|admin|maintain|triage
- permission: push
diff --git a/.github/workflows/conformance.yaml b/.github/workflows/conformance.yaml
new file mode 100644
index 000000000..f7396eaa9
--- /dev/null
+++ b/.github/workflows/conformance.yaml
@@ -0,0 +1,64 @@
+# Copyright 2023 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.
+# Github action job to test core java library features on
+# downstream client libraries before they are released.
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+name: Conformance
+jobs:
+ conformance:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ test-version: [ "v0.0.4" ]
+ py-version: [ 3.13 ]
+ client-type: [ "async", "sync"]
+ # None of the clients currently support reverse scans, execute query plan refresh, retry info, or routing cookie
+ include:
+ - client-type: "async"
+ test_args: "-skip \"PlanRefresh|_Reverse|_WithRetryInfo|_WithRoutingCookie\""
+ - client-type: "sync"
+ test_args: "-skip \"PlanRefresh|_Reverse|_WithRetryInfo|_WithRoutingCookie|_Generic_MultiStream\""
+ fail-fast: false
+ name: "${{ matrix.client-type }} client / python ${{ matrix.py-version }} / test tag ${{ matrix.test-version }}"
+ steps:
+ - uses: actions/checkout@v4
+ name: "Checkout python-bigtable"
+ - uses: actions/checkout@v4
+ name: "Checkout conformance tests"
+ with:
+ repository: googleapis/cloud-bigtable-clients-test
+ ref: ${{ matrix.test-version }}
+ path: cloud-bigtable-clients-test
+ - uses: actions/setup-python@v5
+ with:
+ python-version: ${{ matrix.py-version }}
+ - uses: actions/setup-go@v5
+ with:
+ go-version: '>=1.20.2'
+ - run: chmod +x .kokoro/conformance.sh
+ - run: pip install -e .
+ name: "Install python-bigtable from HEAD"
+ - run: go version
+ - run: .kokoro/conformance.sh
+ name: "Run tests"
+ env:
+ CLIENT_TYPE: ${{ matrix.client-type }}
+ PYTHONUNBUFFERED: 1
+ TEST_ARGS: ${{ matrix.test_args }}
+ PROXY_PORT: 9999
+
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index b46d7305d..2833fe98f 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -8,9 +8,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Setup Python
- uses: actions/setup-python@v3
+ uses: actions/setup-python@v5
with:
python-version: "3.10"
- name: Install nox
@@ -24,9 +24,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Setup Python
- uses: actions/setup-python@v3
+ uses: actions/setup-python@v5
with:
python-version: "3.10"
- name: Install nox
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index f512a4960..9a0598202 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -8,11 +8,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Setup Python
- uses: actions/setup-python@v3
+ uses: actions/setup-python@v5
with:
- python-version: "3.10"
+ python-version: "3.13"
- name: Install nox
run: |
python -m pip install --upgrade setuptools pip wheel
diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml
index f9f07f4de..f2b78a536 100644
--- a/.github/workflows/mypy.yml
+++ b/.github/workflows/mypy.yml
@@ -8,11 +8,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Setup Python
- uses: actions/setup-python@v3
+ uses: actions/setup-python@v5
with:
- python-version: "3.8"
+ python-version: "3.13"
- name: Install nox
run: |
python -m pip install --upgrade setuptools pip wheel
diff --git a/.github/workflows/system_emulated.yml b/.github/workflows/system_emulated.yml
index 303d36724..d8bbbb639 100644
--- a/.github/workflows/system_emulated.yml
+++ b/.github/workflows/system_emulated.yml
@@ -7,20 +7,20 @@ on:
jobs:
run-systests:
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-22.04
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Setup Python
- uses: actions/setup-python@v3
+ uses: actions/setup-python@v5
with:
- python-version: '3.8'
+ python-version: '3.13'
- name: Setup GCloud SDK
- uses: google-github-actions/setup-gcloud@v0.6.0
+ uses: google-github-actions/setup-gcloud@v2.1.1
- name: Install / run Nox
run: |
diff --git a/.github/workflows/unittest.yml b/.github/workflows/unittest.yml
index 5531b0141..dad646c6b 100644
--- a/.github/workflows/unittest.yml
+++ b/.github/workflows/unittest.yml
@@ -5,15 +5,18 @@ on:
name: unittest
jobs:
unit:
- runs-on: ubuntu-latest
+ # TODO(https://github.com/googleapis/gapic-generator-python/issues/2303): use `ubuntu-latest` once this bug is fixed.
+ # Use ubuntu-22.04 until Python 3.7 is removed from the test matrix
+ # https://docs.github.com/en/actions/using-github-hosted-runners/using-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories
+ runs-on: ubuntu-22.04
strategy:
matrix:
- python: ['3.7', '3.8', '3.9', '3.10']
+ python: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12', '3.13', '3.14']
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Setup Python
- uses: actions/setup-python@v3
+ uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}
- name: Install nox
@@ -26,10 +29,11 @@ jobs:
run: |
nox -s unit-${{ matrix.python }}
- name: Upload coverage results
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
- name: coverage-artifacts
+ name: coverage-artifact-${{ matrix.python }}
path: .coverage-${{ matrix.python }}
+ include-hidden-files: true
cover:
runs-on: ubuntu-latest
@@ -37,21 +41,21 @@ jobs:
- unit
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Setup Python
- uses: actions/setup-python@v3
+ uses: actions/setup-python@v5
with:
- python-version: "3.10"
+ python-version: "3.13"
- name: Install coverage
run: |
python -m pip install --upgrade setuptools pip wheel
python -m pip install coverage
- name: Download coverage results
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
- name: coverage-artifacts
path: .coverage-results/
- name: Report coverage results
run: |
- coverage combine .coverage-results/.coverage*
- coverage report --show-missing --fail-under=100
+ find .coverage-results -type f -name '*.zip' -exec unzip {} \;
+ coverage combine .coverage-results/**/.coverage*
+ coverage report --show-missing --fail-under=99
diff --git a/.gitignore b/.gitignore
index b4243ced7..d083ea1dd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -50,6 +50,7 @@ docs.metadata
# Virtual environment
env/
+venv/
# Test logs
coverage.xml
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 000000000..5fa9b1ed5
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,6 @@
+[submodule "python-api-core"]
+ path = python-api-core
+ url = git@github.com:googleapis/python-api-core.git
+[submodule "gapic-generator-fork"]
+ path = gapic-generator-fork
+ url = git@github.com:googleapis/gapic-generator-python.git
diff --git a/.kokoro/build.sh b/.kokoro/build.sh
index 2ab1155b2..d41b45aa1 100755
--- a/.kokoro/build.sh
+++ b/.kokoro/build.sh
@@ -1,5 +1,5 @@
#!/bin/bash
-# Copyright 2018 Google LLC
+# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -15,11 +15,13 @@
set -eo pipefail
+CURRENT_DIR=$(dirname "${BASH_SOURCE[0]}")
+
if [[ -z "${PROJECT_ROOT:-}" ]]; then
- PROJECT_ROOT="github/python-bigtable"
+ PROJECT_ROOT=$(realpath "${CURRENT_DIR}/..")
fi
-cd "${PROJECT_ROOT}"
+pushd "${PROJECT_ROOT}"
# Disable buffering, so that the logs stream through.
export PYTHONUNBUFFERED=1
@@ -28,17 +30,16 @@ export PYTHONUNBUFFERED=1
env | grep KOKORO
# Setup service account credentials.
-export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/service-account.json
+if [[ -f "${KOKORO_GFILE_DIR}/service-account.json" ]]
+then
+ export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/service-account.json
+fi
# Setup project id.
-export PROJECT_ID=$(cat "${KOKORO_GFILE_DIR}/project-id.json")
-
-# Remove old nox
-python3 -m pip uninstall --yes --quiet nox-automation
-
-# Install nox
-python3 -m pip install --upgrade --quiet nox
-python3 -m nox --version
+if [[ -f "${KOKORO_GFILE_DIR}/project-id.json" ]]
+then
+ export PROJECT_ID=$(cat "${KOKORO_GFILE_DIR}/project-id.json")
+fi
# If this is a continuous build, send the test log to the FlakyBot.
# See https://github.com/googleapis/repo-automation-bots/tree/main/packages/flakybot.
@@ -53,7 +54,7 @@ fi
# If NOX_SESSION is set, it only runs the specified session,
# otherwise run all the sessions.
if [[ -n "${NOX_SESSION:-}" ]]; then
- python3 -m nox -s ${NOX_SESSION:-}
+ python3 -m nox -s ${NOX_SESSION:-}
else
- python3 -m nox
+ python3 -m nox
fi
diff --git a/.kokoro/conformance.sh b/.kokoro/conformance.sh
new file mode 100644
index 000000000..fd585142e
--- /dev/null
+++ b/.kokoro/conformance.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+
+# Copyright 2023 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.
+
+set -eo pipefail
+
+## cd to the parent directory, i.e. the root of the git repo
+cd $(dirname $0)/..
+
+# Build and start the proxy in a separate process
+pushd test_proxy
+nohup python test_proxy.py --port $PROXY_PORT --client_type=$CLIENT_TYPE &
+proxyPID=$!
+popd
+
+# Kill proxy on exit
+function cleanup() {
+ echo "Cleanup testbench";
+ kill $proxyPID
+}
+trap cleanup EXIT
+
+# Run the conformance test
+echo "running tests with args: $TEST_ARGS"
+pushd cloud-bigtable-clients-test/tests
+eval "go test -v -proxy_addr=:$PROXY_PORT $TEST_ARGS"
+RETURN_CODE=$?
+popd
+
+echo "exiting with ${RETURN_CODE}"
+exit ${RETURN_CODE}
diff --git a/.kokoro/docker/docs/Dockerfile b/.kokoro/docker/docs/Dockerfile
deleted file mode 100644
index 238b87b9d..000000000
--- a/.kokoro/docker/docs/Dockerfile
+++ /dev/null
@@ -1,83 +0,0 @@
-# Copyright 2020 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.
-
-from ubuntu:22.04
-
-ENV DEBIAN_FRONTEND noninteractive
-
-# Ensure local Python is preferred over distribution Python.
-ENV PATH /usr/local/bin:$PATH
-
-# Install dependencies.
-RUN apt-get update \
- && apt-get install -y --no-install-recommends \
- apt-transport-https \
- build-essential \
- ca-certificates \
- curl \
- dirmngr \
- git \
- gpg-agent \
- graphviz \
- libbz2-dev \
- libdb5.3-dev \
- libexpat1-dev \
- libffi-dev \
- liblzma-dev \
- libreadline-dev \
- libsnappy-dev \
- libssl-dev \
- libsqlite3-dev \
- portaudio19-dev \
- python3-distutils \
- redis-server \
- software-properties-common \
- ssh \
- sudo \
- tcl \
- tcl-dev \
- tk \
- tk-dev \
- uuid-dev \
- wget \
- zlib1g-dev \
- && add-apt-repository universe \
- && apt-get update \
- && apt-get -y install jq \
- && apt-get clean autoclean \
- && apt-get autoremove -y \
- && rm -rf /var/lib/apt/lists/* \
- && rm -f /var/cache/apt/archives/*.deb
-
-###################### Install python 3.8.11
-
-# Download python 3.8.11
-RUN wget https://www.python.org/ftp/python/3.8.11/Python-3.8.11.tgz
-
-# Extract files
-RUN tar -xvf Python-3.8.11.tgz
-
-# Install python 3.8.11
-RUN ./Python-3.8.11/configure --enable-optimizations
-RUN make altinstall
-
-###################### Install pip
-RUN wget -O /tmp/get-pip.py 'https://bootstrap.pypa.io/get-pip.py' \
- && python3 /tmp/get-pip.py \
- && rm /tmp/get-pip.py
-
-# Test pip
-RUN python3 -m pip
-
-CMD ["python3.8"]
diff --git a/.kokoro/docker/docs/fetch_gpg_keys.sh b/.kokoro/docker/docs/fetch_gpg_keys.sh
deleted file mode 100755
index d653dd868..000000000
--- a/.kokoro/docker/docs/fetch_gpg_keys.sh
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/bash
-# Copyright 2020 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.
-
-# A script to fetch gpg keys with retry.
-# Avoid jinja parsing the file.
-#
-
-function retry {
- if [[ "${#}" -le 1 ]]; then
- echo "Usage: ${0} retry_count commands.."
- exit 1
- fi
- local retries=${1}
- local command="${@:2}"
- until [[ "${retries}" -le 0 ]]; do
- $command && return 0
- if [[ $? -ne 0 ]]; then
- echo "command failed, retrying"
- ((retries--))
- fi
- done
- return 1
-}
-
-# 3.6.9, 3.7.5 (Ned Deily)
-retry 3 gpg --keyserver ha.pool.sks-keyservers.net --recv-keys \
- 0D96DF4D4110E5C43FBFB17F2D347EA6AA65421D
-
-# 3.8.0 (Ćukasz Langa)
-retry 3 gpg --keyserver ha.pool.sks-keyservers.net --recv-keys \
- E3FF2839C048B25C084DEBE9B26995E310250568
-
-#
diff --git a/.kokoro/docs/common.cfg b/.kokoro/docs/common.cfg
deleted file mode 100644
index 9b8937c57..000000000
--- a/.kokoro/docs/common.cfg
+++ /dev/null
@@ -1,66 +0,0 @@
-# Format: //devtools/kokoro/config/proto/build.proto
-
-# Build logs will be here
-action {
- define_artifacts {
- regex: "**/*sponge_log.xml"
- }
-}
-
-# Download trampoline resources.
-gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline"
-
-# Use the trampoline script to run in docker.
-build_file: "python-bigtable/.kokoro/trampoline_v2.sh"
-
-# Configure the docker image for kokoro-trampoline.
-env_vars: {
- key: "TRAMPOLINE_IMAGE"
- value: "gcr.io/cloud-devrel-kokoro-resources/python-lib-docs"
-}
-env_vars: {
- key: "TRAMPOLINE_BUILD_FILE"
- value: "github/python-bigtable/.kokoro/publish-docs.sh"
-}
-
-env_vars: {
- key: "STAGING_BUCKET"
- value: "docs-staging"
-}
-
-env_vars: {
- key: "V2_STAGING_BUCKET"
- # Push google cloud library docs to the Cloud RAD bucket `docs-staging-v2`
- value: "docs-staging-v2"
-}
-
-# It will upload the docker image after successful builds.
-env_vars: {
- key: "TRAMPOLINE_IMAGE_UPLOAD"
- value: "true"
-}
-
-# It will always build the docker image.
-env_vars: {
- key: "TRAMPOLINE_DOCKERFILE"
- value: ".kokoro/docker/docs/Dockerfile"
-}
-
-# Fetch the token needed for reporting release status to GitHub
-before_action {
- fetch_keystore {
- keystore_resource {
- keystore_config_id: 73713
- keyname: "yoshi-automation-github-key"
- }
- }
-}
-
-before_action {
- fetch_keystore {
- keystore_resource {
- keystore_config_id: 73713
- keyname: "docuploader_service_account"
- }
- }
-}
\ No newline at end of file
diff --git a/.kokoro/docs/docs-presubmit.cfg b/.kokoro/docs/docs-presubmit.cfg
deleted file mode 100644
index 001770ea6..000000000
--- a/.kokoro/docs/docs-presubmit.cfg
+++ /dev/null
@@ -1,28 +0,0 @@
-# Format: //devtools/kokoro/config/proto/build.proto
-
-env_vars: {
- key: "STAGING_BUCKET"
- value: "gcloud-python-test"
-}
-
-env_vars: {
- key: "V2_STAGING_BUCKET"
- value: "gcloud-python-test"
-}
-
-# We only upload the image in the main `docs` build.
-env_vars: {
- key: "TRAMPOLINE_IMAGE_UPLOAD"
- value: "false"
-}
-
-env_vars: {
- key: "TRAMPOLINE_BUILD_FILE"
- value: "github/python-bigtable/.kokoro/build.sh"
-}
-
-# Only run this nox session.
-env_vars: {
- key: "NOX_SESSION"
- value: "docs docfx"
-}
diff --git a/.kokoro/docs/docs.cfg b/.kokoro/docs/docs.cfg
deleted file mode 100644
index 8f43917d9..000000000
--- a/.kokoro/docs/docs.cfg
+++ /dev/null
@@ -1 +0,0 @@
-# Format: //devtools/kokoro/config/proto/build.proto
\ No newline at end of file
diff --git a/.kokoro/populate-secrets.sh b/.kokoro/populate-secrets.sh
index f52514257..c435402f4 100755
--- a/.kokoro/populate-secrets.sh
+++ b/.kokoro/populate-secrets.sh
@@ -1,5 +1,5 @@
#!/bin/bash
-# Copyright 2020 Google LLC.
+# Copyright 2024 Google LLC.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/.kokoro/presubmit/conformance.cfg b/.kokoro/presubmit/conformance.cfg
new file mode 100644
index 000000000..4f44e8a78
--- /dev/null
+++ b/.kokoro/presubmit/conformance.cfg
@@ -0,0 +1,6 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+env_vars: {
+ key: "NOX_SESSION"
+ value: "conformance"
+}
diff --git a/.kokoro/presubmit/system-3.8.cfg b/.kokoro/presubmit/system-3.9.cfg
similarity index 83%
rename from .kokoro/presubmit/system-3.8.cfg
rename to .kokoro/presubmit/system-3.9.cfg
index f4bcee3db..b8ae66b37 100644
--- a/.kokoro/presubmit/system-3.8.cfg
+++ b/.kokoro/presubmit/system-3.9.cfg
@@ -3,5 +3,5 @@
# Only run this nox session.
env_vars: {
key: "NOX_SESSION"
- value: "system-3.8"
+ value: "system-3.9"
}
\ No newline at end of file
diff --git a/.kokoro/presubmit/system.cfg b/.kokoro/presubmit/system.cfg
new file mode 100644
index 000000000..30956a3ab
--- /dev/null
+++ b/.kokoro/presubmit/system.cfg
@@ -0,0 +1,7 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+# Only run this nox session.
+env_vars: {
+ key: "NOX_SESSION"
+ value: "system-3.10"
+}
diff --git a/.kokoro/publish-docs.sh b/.kokoro/publish-docs.sh
deleted file mode 100755
index 8acb14e80..000000000
--- a/.kokoro/publish-docs.sh
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/bin/bash
-# Copyright 2020 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
-#
-# https://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.
-
-set -eo pipefail
-
-# Disable buffering, so that the logs stream through.
-export PYTHONUNBUFFERED=1
-
-export PATH="${HOME}/.local/bin:${PATH}"
-
-# Install nox
-python3 -m pip install --user --upgrade --quiet nox
-python3 -m nox --version
-
-# build docs
-nox -s docs
-
-python3 -m pip install --user gcp-docuploader
-
-# create metadata
-python3 -m docuploader create-metadata \
- --name=$(jq --raw-output '.name // empty' .repo-metadata.json) \
- --version=$(python3 setup.py --version) \
- --language=$(jq --raw-output '.language // empty' .repo-metadata.json) \
- --distribution-name=$(python3 setup.py --name) \
- --product-page=$(jq --raw-output '.product_documentation // empty' .repo-metadata.json) \
- --github-repository=$(jq --raw-output '.repo // empty' .repo-metadata.json) \
- --issue-tracker=$(jq --raw-output '.issue_tracker // empty' .repo-metadata.json)
-
-cat docs.metadata
-
-# upload docs
-python3 -m docuploader upload docs/_build/html --metadata-file docs.metadata --staging-bucket "${STAGING_BUCKET}"
-
-
-# docfx yaml files
-nox -s docfx
-
-# create metadata.
-python3 -m docuploader create-metadata \
- --name=$(jq --raw-output '.name // empty' .repo-metadata.json) \
- --version=$(python3 setup.py --version) \
- --language=$(jq --raw-output '.language // empty' .repo-metadata.json) \
- --distribution-name=$(python3 setup.py --name) \
- --product-page=$(jq --raw-output '.product_documentation // empty' .repo-metadata.json) \
- --github-repository=$(jq --raw-output '.repo // empty' .repo-metadata.json) \
- --issue-tracker=$(jq --raw-output '.issue_tracker // empty' .repo-metadata.json)
-
-cat docs.metadata
-
-# upload docs
-python3 -m docuploader upload docs/_build/html/docfx_yaml --metadata-file docs.metadata --destination-prefix docfx --staging-bucket "${V2_STAGING_BUCKET}"
diff --git a/.kokoro/release.sh b/.kokoro/release.sh
deleted file mode 100755
index f0cb9d5db..000000000
--- a/.kokoro/release.sh
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/bash
-# Copyright 2020 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
-#
-# https://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.
-
-set -eo pipefail
-
-# Start the releasetool reporter
-python3 -m pip install gcp-releasetool
-python3 -m releasetool publish-reporter-script > /tmp/publisher-script; source /tmp/publisher-script
-
-# Ensure that we have the latest versions of Twine, Wheel, and Setuptools.
-python3 -m pip install --upgrade twine wheel setuptools
-
-# Disable buffering, so that the logs stream through.
-export PYTHONUNBUFFERED=1
-
-# Move into the package, build the distribution and upload.
-TWINE_PASSWORD=$(cat "${KOKORO_KEYSTORE_DIR}/73713_google-cloud-pypi-token-keystore-1")
-cd github/python-bigtable
-python3 setup.py sdist bdist_wheel
-twine upload --username __token__ --password "${TWINE_PASSWORD}" dist/*
diff --git a/.kokoro/release/common.cfg b/.kokoro/release/common.cfg
deleted file mode 100644
index 8477e4ca6..000000000
--- a/.kokoro/release/common.cfg
+++ /dev/null
@@ -1,40 +0,0 @@
-# Format: //devtools/kokoro/config/proto/build.proto
-
-# Build logs will be here
-action {
- define_artifacts {
- regex: "**/*sponge_log.xml"
- }
-}
-
-# Download trampoline resources.
-gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline"
-
-# Use the trampoline script to run in docker.
-build_file: "python-bigtable/.kokoro/trampoline.sh"
-
-# Configure the docker image for kokoro-trampoline.
-env_vars: {
- key: "TRAMPOLINE_IMAGE"
- value: "gcr.io/cloud-devrel-kokoro-resources/python-multi"
-}
-env_vars: {
- key: "TRAMPOLINE_BUILD_FILE"
- value: "github/python-bigtable/.kokoro/release.sh"
-}
-
-# Fetch PyPI password
-before_action {
- fetch_keystore {
- keystore_resource {
- keystore_config_id: 73713
- keyname: "google-cloud-pypi-token-keystore-1"
- }
- }
-}
-
-# Tokens needed to report release status back to GitHub
-env_vars: {
- key: "SECRET_MANAGER_KEYS"
- value: "releasetool-publish-reporter-app,releasetool-publish-reporter-googleapis-installation,releasetool-publish-reporter-pem"
-}
diff --git a/.kokoro/release/release.cfg b/.kokoro/release/release.cfg
deleted file mode 100644
index 8f43917d9..000000000
--- a/.kokoro/release/release.cfg
+++ /dev/null
@@ -1 +0,0 @@
-# Format: //devtools/kokoro/config/proto/build.proto
\ No newline at end of file
diff --git a/.kokoro/samples/python3.11/common.cfg b/.kokoro/samples/python3.11/common.cfg
new file mode 100644
index 000000000..467d405ae
--- /dev/null
+++ b/.kokoro/samples/python3.11/common.cfg
@@ -0,0 +1,40 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+# Build logs will be here
+action {
+ define_artifacts {
+ regex: "**/*sponge_log.xml"
+ }
+}
+
+# Specify which tests to run
+env_vars: {
+ key: "RUN_TESTS_SESSION"
+ value: "py-3.11"
+}
+
+# Declare build specific Cloud project.
+env_vars: {
+ key: "BUILD_SPECIFIC_GCLOUD_PROJECT"
+ value: "python-docs-samples-tests-311"
+}
+
+env_vars: {
+ key: "TRAMPOLINE_BUILD_FILE"
+ value: "github/python-bigtable/.kokoro/test-samples.sh"
+}
+
+# Configure the docker image for kokoro-trampoline.
+env_vars: {
+ key: "TRAMPOLINE_IMAGE"
+ value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker"
+}
+
+# Download secrets for samples
+gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples"
+
+# Download trampoline resources.
+gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline"
+
+# Use the trampoline script to run in docker.
+build_file: "python-bigtable/.kokoro/trampoline_v2.sh"
\ No newline at end of file
diff --git a/.kokoro/samples/python3.11/continuous.cfg b/.kokoro/samples/python3.11/continuous.cfg
new file mode 100644
index 000000000..a1c8d9759
--- /dev/null
+++ b/.kokoro/samples/python3.11/continuous.cfg
@@ -0,0 +1,6 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+env_vars: {
+ key: "INSTALL_LIBRARY_FROM_SOURCE"
+ value: "True"
+}
\ No newline at end of file
diff --git a/.kokoro/samples/python3.11/periodic-head.cfg b/.kokoro/samples/python3.11/periodic-head.cfg
new file mode 100644
index 000000000..be25a34f9
--- /dev/null
+++ b/.kokoro/samples/python3.11/periodic-head.cfg
@@ -0,0 +1,11 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+env_vars: {
+ key: "INSTALL_LIBRARY_FROM_SOURCE"
+ value: "True"
+}
+
+env_vars: {
+ key: "TRAMPOLINE_BUILD_FILE"
+ value: "github/python-bigtable/.kokoro/test-samples-against-head.sh"
+}
diff --git a/.kokoro/samples/python3.11/periodic.cfg b/.kokoro/samples/python3.11/periodic.cfg
new file mode 100644
index 000000000..71cd1e597
--- /dev/null
+++ b/.kokoro/samples/python3.11/periodic.cfg
@@ -0,0 +1,6 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+env_vars: {
+ key: "INSTALL_LIBRARY_FROM_SOURCE"
+ value: "False"
+}
diff --git a/.kokoro/samples/python3.11/presubmit.cfg b/.kokoro/samples/python3.11/presubmit.cfg
new file mode 100644
index 000000000..a1c8d9759
--- /dev/null
+++ b/.kokoro/samples/python3.11/presubmit.cfg
@@ -0,0 +1,6 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+env_vars: {
+ key: "INSTALL_LIBRARY_FROM_SOURCE"
+ value: "True"
+}
\ No newline at end of file
diff --git a/.kokoro/samples/python3.12/common.cfg b/.kokoro/samples/python3.12/common.cfg
new file mode 100644
index 000000000..34e0a95f3
--- /dev/null
+++ b/.kokoro/samples/python3.12/common.cfg
@@ -0,0 +1,40 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+# Build logs will be here
+action {
+ define_artifacts {
+ regex: "**/*sponge_log.xml"
+ }
+}
+
+# Specify which tests to run
+env_vars: {
+ key: "RUN_TESTS_SESSION"
+ value: "py-3.12"
+}
+
+# Declare build specific Cloud project.
+env_vars: {
+ key: "BUILD_SPECIFIC_GCLOUD_PROJECT"
+ value: "python-docs-samples-tests-312"
+}
+
+env_vars: {
+ key: "TRAMPOLINE_BUILD_FILE"
+ value: "github/python-bigtable/.kokoro/test-samples.sh"
+}
+
+# Configure the docker image for kokoro-trampoline.
+env_vars: {
+ key: "TRAMPOLINE_IMAGE"
+ value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker"
+}
+
+# Download secrets for samples
+gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples"
+
+# Download trampoline resources.
+gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline"
+
+# Use the trampoline script to run in docker.
+build_file: "python-bigtable/.kokoro/trampoline_v2.sh"
\ No newline at end of file
diff --git a/.kokoro/samples/python3.12/continuous.cfg b/.kokoro/samples/python3.12/continuous.cfg
new file mode 100644
index 000000000..a1c8d9759
--- /dev/null
+++ b/.kokoro/samples/python3.12/continuous.cfg
@@ -0,0 +1,6 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+env_vars: {
+ key: "INSTALL_LIBRARY_FROM_SOURCE"
+ value: "True"
+}
\ No newline at end of file
diff --git a/.kokoro/samples/python3.12/periodic-head.cfg b/.kokoro/samples/python3.12/periodic-head.cfg
new file mode 100644
index 000000000..be25a34f9
--- /dev/null
+++ b/.kokoro/samples/python3.12/periodic-head.cfg
@@ -0,0 +1,11 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+env_vars: {
+ key: "INSTALL_LIBRARY_FROM_SOURCE"
+ value: "True"
+}
+
+env_vars: {
+ key: "TRAMPOLINE_BUILD_FILE"
+ value: "github/python-bigtable/.kokoro/test-samples-against-head.sh"
+}
diff --git a/.kokoro/samples/python3.12/periodic.cfg b/.kokoro/samples/python3.12/periodic.cfg
new file mode 100644
index 000000000..71cd1e597
--- /dev/null
+++ b/.kokoro/samples/python3.12/periodic.cfg
@@ -0,0 +1,6 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+env_vars: {
+ key: "INSTALL_LIBRARY_FROM_SOURCE"
+ value: "False"
+}
diff --git a/.kokoro/samples/python3.12/presubmit.cfg b/.kokoro/samples/python3.12/presubmit.cfg
new file mode 100644
index 000000000..a1c8d9759
--- /dev/null
+++ b/.kokoro/samples/python3.12/presubmit.cfg
@@ -0,0 +1,6 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+env_vars: {
+ key: "INSTALL_LIBRARY_FROM_SOURCE"
+ value: "True"
+}
\ No newline at end of file
diff --git a/.kokoro/samples/python3.13/common.cfg b/.kokoro/samples/python3.13/common.cfg
new file mode 100644
index 000000000..15ba807cb
--- /dev/null
+++ b/.kokoro/samples/python3.13/common.cfg
@@ -0,0 +1,40 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+# Build logs will be here
+action {
+ define_artifacts {
+ regex: "**/*sponge_log.xml"
+ }
+}
+
+# Specify which tests to run
+env_vars: {
+ key: "RUN_TESTS_SESSION"
+ value: "py-3.13"
+}
+
+# Declare build specific Cloud project.
+env_vars: {
+ key: "BUILD_SPECIFIC_GCLOUD_PROJECT"
+ value: "python-docs-samples-tests-313"
+}
+
+env_vars: {
+ key: "TRAMPOLINE_BUILD_FILE"
+ value: "github/python-bigtable/.kokoro/test-samples.sh"
+}
+
+# Configure the docker image for kokoro-trampoline.
+env_vars: {
+ key: "TRAMPOLINE_IMAGE"
+ value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker"
+}
+
+# Download secrets for samples
+gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples"
+
+# Download trampoline resources.
+gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline"
+
+# Use the trampoline script to run in docker.
+build_file: "python-bigtable/.kokoro/trampoline_v2.sh"
diff --git a/.kokoro/samples/python3.13/continuous.cfg b/.kokoro/samples/python3.13/continuous.cfg
new file mode 100644
index 000000000..a1c8d9759
--- /dev/null
+++ b/.kokoro/samples/python3.13/continuous.cfg
@@ -0,0 +1,6 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+env_vars: {
+ key: "INSTALL_LIBRARY_FROM_SOURCE"
+ value: "True"
+}
\ No newline at end of file
diff --git a/.kokoro/samples/python3.13/periodic-head.cfg b/.kokoro/samples/python3.13/periodic-head.cfg
new file mode 100644
index 000000000..be25a34f9
--- /dev/null
+++ b/.kokoro/samples/python3.13/periodic-head.cfg
@@ -0,0 +1,11 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+env_vars: {
+ key: "INSTALL_LIBRARY_FROM_SOURCE"
+ value: "True"
+}
+
+env_vars: {
+ key: "TRAMPOLINE_BUILD_FILE"
+ value: "github/python-bigtable/.kokoro/test-samples-against-head.sh"
+}
diff --git a/.kokoro/samples/python3.13/periodic.cfg b/.kokoro/samples/python3.13/periodic.cfg
new file mode 100644
index 000000000..71cd1e597
--- /dev/null
+++ b/.kokoro/samples/python3.13/periodic.cfg
@@ -0,0 +1,6 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+env_vars: {
+ key: "INSTALL_LIBRARY_FROM_SOURCE"
+ value: "False"
+}
diff --git a/.kokoro/samples/python3.13/presubmit.cfg b/.kokoro/samples/python3.13/presubmit.cfg
new file mode 100644
index 000000000..a1c8d9759
--- /dev/null
+++ b/.kokoro/samples/python3.13/presubmit.cfg
@@ -0,0 +1,6 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+env_vars: {
+ key: "INSTALL_LIBRARY_FROM_SOURCE"
+ value: "True"
+}
\ No newline at end of file
diff --git a/.kokoro/samples/python3.14/common.cfg b/.kokoro/samples/python3.14/common.cfg
new file mode 100644
index 000000000..a9ea06119
--- /dev/null
+++ b/.kokoro/samples/python3.14/common.cfg
@@ -0,0 +1,40 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+# Build logs will be here
+action {
+ define_artifacts {
+ regex: "**/*sponge_log.xml"
+ }
+}
+
+# Specify which tests to run
+env_vars: {
+ key: "RUN_TESTS_SESSION"
+ value: "py-3.14"
+}
+
+# Declare build specific Cloud project.
+env_vars: {
+ key: "BUILD_SPECIFIC_GCLOUD_PROJECT"
+ value: "python-docs-samples-tests-314"
+}
+
+env_vars: {
+ key: "TRAMPOLINE_BUILD_FILE"
+ value: "github/python-bigtable/.kokoro/test-samples.sh"
+}
+
+# Configure the docker image for kokoro-trampoline.
+env_vars: {
+ key: "TRAMPOLINE_IMAGE"
+ value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker"
+}
+
+# Download secrets for samples
+gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples"
+
+# Download trampoline resources.
+gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline"
+
+# Use the trampoline script to run in docker.
+build_file: "python-bigtable/.kokoro/trampoline_v2.sh"
diff --git a/.kokoro/samples/python3.14/continuous.cfg b/.kokoro/samples/python3.14/continuous.cfg
new file mode 100644
index 000000000..a1c8d9759
--- /dev/null
+++ b/.kokoro/samples/python3.14/continuous.cfg
@@ -0,0 +1,6 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+env_vars: {
+ key: "INSTALL_LIBRARY_FROM_SOURCE"
+ value: "True"
+}
\ No newline at end of file
diff --git a/.kokoro/samples/python3.14/periodic-head.cfg b/.kokoro/samples/python3.14/periodic-head.cfg
new file mode 100644
index 000000000..be25a34f9
--- /dev/null
+++ b/.kokoro/samples/python3.14/periodic-head.cfg
@@ -0,0 +1,11 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+env_vars: {
+ key: "INSTALL_LIBRARY_FROM_SOURCE"
+ value: "True"
+}
+
+env_vars: {
+ key: "TRAMPOLINE_BUILD_FILE"
+ value: "github/python-bigtable/.kokoro/test-samples-against-head.sh"
+}
diff --git a/.kokoro/samples/python3.14/periodic.cfg b/.kokoro/samples/python3.14/periodic.cfg
new file mode 100644
index 000000000..71cd1e597
--- /dev/null
+++ b/.kokoro/samples/python3.14/periodic.cfg
@@ -0,0 +1,6 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+env_vars: {
+ key: "INSTALL_LIBRARY_FROM_SOURCE"
+ value: "False"
+}
diff --git a/.kokoro/samples/python3.14/presubmit.cfg b/.kokoro/samples/python3.14/presubmit.cfg
new file mode 100644
index 000000000..a1c8d9759
--- /dev/null
+++ b/.kokoro/samples/python3.14/presubmit.cfg
@@ -0,0 +1,6 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+env_vars: {
+ key: "INSTALL_LIBRARY_FROM_SOURCE"
+ value: "True"
+}
\ No newline at end of file
diff --git a/.kokoro/test-samples-against-head.sh b/.kokoro/test-samples-against-head.sh
index ba3a707b0..e9d8bd79a 100755
--- a/.kokoro/test-samples-against-head.sh
+++ b/.kokoro/test-samples-against-head.sh
@@ -1,5 +1,5 @@
#!/bin/bash
-# Copyright 2020 Google LLC
+# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/.kokoro/test-samples-impl.sh b/.kokoro/test-samples-impl.sh
index 2c6500cae..53e365bc4 100755
--- a/.kokoro/test-samples-impl.sh
+++ b/.kokoro/test-samples-impl.sh
@@ -1,5 +1,5 @@
#!/bin/bash
-# Copyright 2021 Google LLC
+# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -33,7 +33,8 @@ export PYTHONUNBUFFERED=1
env | grep KOKORO
# Install nox
-python3.9 -m pip install --upgrade --quiet nox
+# `virtualenv==20.26.6` is added for Python 3.7 compatibility
+python3.9 -m pip install --upgrade --quiet nox virtualenv==20.26.6
# Use secrets acessor service account to get secrets
if [[ -f "${KOKORO_GFILE_DIR}/secrets_viewer_service_account.json" ]]; then
diff --git a/.kokoro/test-samples.sh b/.kokoro/test-samples.sh
index 11c042d34..7933d8201 100755
--- a/.kokoro/test-samples.sh
+++ b/.kokoro/test-samples.sh
@@ -1,5 +1,5 @@
#!/bin/bash
-# Copyright 2020 Google LLC
+# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/.kokoro/trampoline.sh b/.kokoro/trampoline.sh
index f39236e94..48f796997 100755
--- a/.kokoro/trampoline.sh
+++ b/.kokoro/trampoline.sh
@@ -1,5 +1,5 @@
#!/bin/bash
-# Copyright 2017 Google Inc.
+# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/.kokoro/trampoline_v2.sh b/.kokoro/trampoline_v2.sh
index 4af6cdc26..d03f92dfc 100755
--- a/.kokoro/trampoline_v2.sh
+++ b/.kokoro/trampoline_v2.sh
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
-# Copyright 2020 Google LLC
+# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -26,8 +26,8 @@
# To run this script, first download few files from gcs to /dev/shm.
# (/dev/shm is passed into the container as KOKORO_GFILE_DIR).
#
-# gsutil cp gs://cloud-devrel-kokoro-resources/python-docs-samples/secrets_viewer_service_account.json /dev/shm
-# gsutil cp gs://cloud-devrel-kokoro-resources/python-docs-samples/automl_secrets.txt /dev/shm
+# gcloud storage cp gs://cloud-devrel-kokoro-resources/python-docs-samples/secrets_viewer_service_account.json /dev/shm
+# gcloud storage cp gs://cloud-devrel-kokoro-resources/python-docs-samples/automl_secrets.txt /dev/shm
#
# Then run the script.
# .kokoro/trampoline_v2.sh
diff --git a/.librarian/generator-input/.repo-metadata.json b/.librarian/generator-input/.repo-metadata.json
new file mode 100644
index 000000000..9de4b5f92
--- /dev/null
+++ b/.librarian/generator-input/.repo-metadata.json
@@ -0,0 +1,80 @@
+{
+ "name": "bigtable",
+ "name_pretty": "Cloud Bigtable",
+ "product_documentation": "https://cloud.google.com/bigtable",
+ "client_documentation": "https://cloud.google.com/python/docs/reference/bigtable/latest",
+ "issue_tracker": "https://issuetracker.google.com/savedsearches/559777",
+ "release_level": "stable",
+ "language": "python",
+ "library_type": "GAPIC_COMBO",
+ "repo": "googleapis/python-bigtable",
+ "distribution_name": "google-cloud-bigtable",
+ "api_id": "bigtable.googleapis.com",
+ "requires_billing": true,
+ "samples": [
+ {
+ "name": "Hello World in Cloud Bigtable",
+ "description": "Demonstrates how to connect to Cloud Bigtable and run some basic operations. More information available at: https://cloud.google.com/bigtable/docs/samples-python-hello",
+ "file": "main.py",
+ "runnable": true,
+ "custom_content": "
usage: main.py [-h] [--table TABLE] project_id instance_id
Demonstrates how to connect to Cloud Bigtable and run some basic operations.
Prerequisites: - Create a Cloud Bigtable cluster.
https://cloud.google.com/bigtable/docs/creating-cluster - Set your Google
Application Default Credentials.
https://developers.google.com/identity/protocols/application-default-
credentials
positional arguments:
project_id Your Cloud Platform project ID.
instance_id ID of the Cloud Bigtable instance to connect to.
optional arguments:
-h, --help show this help message and exit
--table TABLE Table to create and destroy. (default: Hello-Bigtable)
",
+ "override_path": "hello"
+ },
+ {
+ "name": "Hello World using HappyBase",
+ "description": "This sample demonstrates using the Google Cloud Client Library HappyBase package, an implementation of the HappyBase API to connect to and interact with Cloud Bigtable. More information available at: https://cloud.google.com/bigtable/docs/samples-python-hello-happybase",
+ "file": "main.py",
+ "runnable": true,
+ "custom_content": "usage: main.py [-h] [--table TABLE] project_id instance_id
Demonstrates how to connect to Cloud Bigtable and run some basic operations.
Prerequisites: - Create a Cloud Bigtable cluster.
https://cloud.google.com/bigtable/docs/creating-cluster - Set your Google
Application Default Credentials.
https://developers.google.com/identity/protocols/application-default-
credentials
positional arguments:
project_id Your Cloud Platform project ID.
instance_id ID of the Cloud Bigtable instance to connect to.
optional arguments:
-h, --help show this help message and exit
--table TABLE Table to create and destroy. (default: Hello-Bigtable)
",
+ "override_path": "hello_happybase"
+ },
+ {
+ "name": "cbt Command Demonstration",
+ "description": "This page explains how to use the cbt command to connect to a Cloud Bigtable instance, perform basic administrative tasks, and read and write data in a table. More information about this quickstart is available at https://cloud.google.com/bigtable/docs/quickstart-cbt",
+ "file": "instanceadmin.py",
+ "runnable": true,
+ "custom_content": "usage: instanceadmin.py [-h] [run] [dev-instance] [del-instance] [add-cluster] [del-cluster] project_id instance_id cluster_id
Demonstrates how to connect to Cloud Bigtable and run some basic operations.
Prerequisites: - Create a Cloud Bigtable cluster.
https://cloud.google.com/bigtable/docs/creating-cluster - Set your Google
Application Default Credentials.
https://developers.google.com/identity/protocols/application-default-
credentials
positional arguments:
project_id Your Cloud Platform project ID.
instance_id ID of the Cloud Bigtable instance to connect to.
optional arguments:
-h, --help show this help message and exit
--table TABLE Table to create and destroy. (default: Hello-Bigtable)
",
+ "override_path": "instanceadmin"
+ },
+ {
+ "name": "Metric Scaler",
+ "description": "This sample demonstrates how to use Stackdriver Monitoring to scale Cloud Bigtable based on CPU usage.",
+ "file": "metricscaler.py",
+ "runnable": true,
+ "custom_content": "usage: metricscaler.py [-h] [--high_cpu_threshold HIGH_CPU_THRESHOLD] [--low_cpu_threshold LOW_CPU_THRESHOLD] [--short_sleep SHORT_SLEEP] [--long_sleep LONG_SLEEP] bigtable_instance bigtable_cluster
usage: metricscaler.py [-h] [--high_cpu_threshold HIGH_CPU_THRESHOLD]
[--low_cpu_threshold LOW_CPU_THRESHOLD]
[--short_sleep SHORT_SLEEP] [--long_sleep LONG_SLEEP]
bigtable_instance bigtable_cluster
Scales Cloud Bigtable clusters based on CPU usage.
positional arguments:
bigtable_instance ID of the Cloud Bigtable instance to connect to.
bigtable_cluster ID of the Cloud Bigtable cluster to connect to.
optional arguments:
-h, --help show this help message and exit
--high_cpu_threshold HIGH_CPU_THRESHOLD
If Cloud Bigtable CPU usage is above this threshold,
scale up
--low_cpu_threshold LOW_CPU_THRESHOLD
If Cloud Bigtable CPU usage is below this threshold,
scale down
--short_sleep SHORT_SLEEP
How long to sleep in seconds between checking metrics
after no scale operation
--long_sleep LONG_SLEEP
How long to sleep in seconds between checking metrics
after a scaling operation
",
+ "override_path": "metricscaler"
+ },
+ {
+ "name": "Quickstart",
+ "description": "Demonstrates of Cloud Bigtable. This sample creates a Bigtable client, connects to an instance and then to a table, then closes the connection.",
+ "file": "main.py",
+ "runnable": true,
+ "custom_content": "usage: main.py [-h] [--table TABLE] project_id instance_id
positional arguments:
project_id Your Cloud Platform project ID.
instance_id ID of the Cloud Bigtable instance to connect to.
optional arguments:
-h, --help show this help message and exit
--table TABLE Existing table used in the quickstart. (default: my-table)
",
+ "override_path": "quickstart"
+ },
+ {
+ "name": "Quickstart using HappyBase",
+ "description": "Demonstrates of Cloud Bigtable using HappyBase. This sample creates a Bigtable client, connects to an instance and then to a table, then closes the connection.",
+ "file": "main.py",
+ "runnable": true,
+ "custom_content": "usage: main.py [-h] [--table TABLE] project_id instance_id
usage: main.py [-h] [--table TABLE] project_id instance_id
positional arguments:
project_id Your Cloud Platform project ID.
instance_id ID of the Cloud Bigtable instance to connect to.
optional arguments:
-h, --help show this help message and exit
--table TABLE Existing table used in the quickstart. (default: my-table)usage: tableadmin.py [-h] [run] [delete] [--table TABLE] project_id instance_id
Demonstrates how to connect to Cloud Bigtable and run some basic operations.
Prerequisites: - Create a Cloud Bigtable cluster.
https://cloud.google.com/bigtable/docs/creating-cluster - Set your Google
Application Default Credentials.
https://developers.google.com/identity/protocols/application-default-
credentials
positional arguments:
project_id Your Cloud Platform project ID.
instance_id ID of the Cloud Bigtable instance to connect to.
optional arguments:
-h, --help show this help message and exit
--table TABLE Table to create and destroy. (default: Hello-Bigtable)
",
+ "override_path": "tableadmin"
+ }
+ ],
+ "default_version": "v2",
+ "codeowner_team": "@googleapis/api-bigtable @googleapis/api-bigtable-partners",
+ "api_shortname": "bigtable"
+}
diff --git a/.librarian/generator-input/librarian.py b/.librarian/generator-input/librarian.py
new file mode 100644
index 000000000..5b943d24b
--- /dev/null
+++ b/.librarian/generator-input/librarian.py
@@ -0,0 +1,266 @@
+# Copyright 2018 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.
+
+"""This script is used to synthesize generated parts of this library."""
+
+from pathlib import Path
+import re
+import textwrap
+from typing import List, Optional
+
+import synthtool as s
+from synthtool import gcp, _tracked_paths
+from synthtool.languages import python
+from synthtool.sources import templates
+
+common = gcp.CommonTemplates()
+
+# These flags are needed because certain post-processing operations
+# append things after a certain line of text, and can infinitely loop
+# in a Github PR. We use these flags to only do those operations
+# on fresh copies of files found in googleapis-gen, and not on user-submitted
+# changes.
+is_fresh_admin_copy = False
+is_fresh_admin_v2_copy = False
+is_fresh_admin_docs_copy = False
+
+for library in s.get_staging_dirs("v2"):
+ s.move(library / "google/cloud/bigtable_v2")
+ is_fresh_admin_copy = \
+ s.move(library / "google/cloud/bigtable_admin")
+ is_fresh_admin_v2_copy = \
+ s.move(library / "google/cloud/bigtable_admin_v2")
+ s.move(library / "tests")
+ s.move(library / "samples")
+ s.move(library / "scripts")
+ is_fresh_admin_docs_copy = \
+ s.move(library / "docs/bigtable_admin_v2", destination="docs/admin_client")
+
+s.remove_staging_dirs()
+
+# ----------------------------------------------------------------------------
+# Add templated files
+# ----------------------------------------------------------------------------
+templated_files = common.py_library(
+ samples=True, # set to True only if there are samples
+ split_system_tests=True,
+ microgenerator=True,
+ cov_level=99,
+ system_test_external_dependencies=[
+ "pytest-asyncio==0.21.2",
+ ],
+ system_test_python_versions=["3.9"],
+ unit_test_python_versions=["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"],
+ default_python_version="3.13",
+)
+
+s.move(templated_files, excludes=[".coveragerc", "README.rst", ".github/**", ".kokoro/**", "noxfile.py", "renovate.json"])
+
+
+s.shell.run(["nox", "-s", "blacken"], hide_output=False)
+
+# ----------------------------------------------------------------------------
+# Always supply app_profile_id in routing headers: https://github.com/googleapis/python-bigtable/pull/1109
+# TODO: remove after backend no longer requires empty strings
+# ----------------------------------------------------------------------------
+for file in ["async_client.py", "client.py"]:
+ s.replace(
+ f"google/cloud/bigtable_v2/services/bigtable/{file}",
+ "if request.app_profile_id:",
+ "if True: # always attach app_profile_id, even if empty string"
+ )
+# fix tests
+s.replace(
+ "tests/unit/gapic/bigtable_v2/test_bigtable.py",
+ 'assert \(\n\s*gapic_v1\.routing_header\.to_grpc_metadata\(expected_headers\) in kw\["metadata"\]\n.*',
+ """# assert the expected headers are present, in any order
+ routing_string = next(
+ iter([m[1] for m in kw["metadata"] if m[0] == "x-goog-request-params"])
+ )
+ assert all([f"{k}={v}" in routing_string for k, v in expected_headers.items()])"""
+)
+s.replace(
+ "tests/unit/gapic/bigtable_v2/test_bigtable.py",
+ 'expected_headers = {"name": "projects/sample1/instances/sample2"}',
+ """expected_headers = {
+ "name": "projects/sample1/instances/sample2",
+ "app_profile_id": "",
+ }"""
+)
+s.replace(
+ "tests/unit/gapic/bigtable_v2/test_bigtable.py",
+ """
+ expected_headers = {
+ "table_name": "projects/sample1/instances/sample2/tables/sample3"
+ }
+""",
+ """
+ expected_headers = {
+ "table_name": "projects/sample1/instances/sample2/tables/sample3",
+ "app_profile_id": "",
+ }
+"""
+)
+
+# ----------------------------------------------------------------------------
+# Samples templates
+# ----------------------------------------------------------------------------
+
+python.py_samples(skip_readmes=True)
+
+# --------------------------------------------------------------------------
+# Admin Overlay work
+# --------------------------------------------------------------------------
+
+# Add overlay imports to top level __init__.py files in admin_v2 and admin at the end
+# of each file, after the __all__ definition. These changes should only be done on fresh
+# copies of the __init__.py files.
+def add_overlay_to_init_py(init_py_location, import_statements, should_add):
+ if should_add:
+ s.replace(
+ init_py_location,
+ r"(?s)(^__all__ = \(.*\)$)",
+ r"\1\n\n" + import_statements
+ )
+
+add_overlay_to_init_py(
+ "google/cloud/bigtable_admin_v2/__init__.py",
+ """from .overlay import * # noqa: F403\n
+__all__ += overlay.__all__ # noqa: F405""",
+ is_fresh_admin_v2_copy,
+)
+
+add_overlay_to_init_py(
+ "google/cloud/bigtable_admin/__init__.py",
+ """import google.cloud.bigtable_admin_v2.overlay # noqa: F401
+from google.cloud.bigtable_admin_v2.overlay import * # noqa: F401, F403
+
+__all__ += google.cloud.bigtable_admin_v2.overlay.__all__""",
+ is_fresh_admin_copy,
+)
+
+# Replace all instances of BaseBigtableTableAdminClient/BaseBigtableAdminAsyncClient
+# in samples and docstrings with BigtableTableAdminClient/BigtableTableAdminAsyncClient
+s.replace(
+ [
+ "google/cloud/bigtable_admin_v2/services/*/client.py",
+ "google/cloud/bigtable_admin_v2/services/*/async_client.py",
+ "samples/generated_samples/bigtableadmin_v2_*.py"
+ ],
+ r"client = bigtable_admin_v2\.Base(BigtableTableAdmin(Async)?Client\(\))",
+ r"client = bigtable_admin_v2.\1"
+)
+
+# Fix an improperly formatted table that breaks nox -s docs.
+s.replace(
+ "google/cloud/bigtable_admin_v2/types/table.py",
+ """ For example, if \\\\_key =
+ "some_id#2024-04-30#\\\\x00\\\\x13\\\\x00\\\\xf3" with the following
+ schema: \\{ fields \\{ field_name: "id" type \\{ string \\{
+ encoding: utf8_bytes \\{\\} \\} \\} \\} fields \\{ field_name: "date"
+ type \\{ string \\{ encoding: utf8_bytes \\{\\} \\} \\} \\} fields \\{
+ field_name: "product_code" type \\{ int64 \\{ encoding:
+ big_endian_bytes \\{\\} \\} \\} \\} encoding \\{ delimited_bytes \\{
+ delimiter: "#" \\} \\} \\}
+
+ \\| The decoded key parts would be: id = "some_id", date =
+ "2024-04-30", product_code = 1245427 The query "SELECT
+ \\\\_key, product_code FROM table" will return two columns:
+ /------------------------------------------------------
+ \\| \\\\\\| \\\\_key \\\\\\| product_code \\\\\\| \\\\\\|
+ --------------------------------------\\|--------------\\\\\\| \\\\\\|
+ "some_id#2024-04-30#\\\\x00\\\\x13\\\\x00\\\\xf3" \\\\\\| 1245427 \\\\\\|
+ ------------------------------------------------------/
+""",
+ textwrap.indent(
+ """For example, if \\\\_key =
+"some_id#2024-04-30#\\\\x00\\\\x13\\\\x00\\\\xf3" with the following
+schema:
+
+.. code-block::
+
+ {
+ fields {
+ field_name: "id"
+ type { string { encoding: utf8_bytes {} } }
+ }
+ fields {
+ field_name: "date"
+ type { string { encoding: utf8_bytes {} } }
+ }
+ fields {
+ field_name: "product_code"
+ type { int64 { encoding: big_endian_bytes {} } }
+ }
+ encoding { delimited_bytes { delimiter: "#" } }
+ }
+
+The decoded key parts would be:
+id = "some_id", date = "2024-04-30", product_code = 1245427
+The query "SELECT \\\\_key, product_code FROM table" will return
+two columns:
+
++========================================+==============+
+| \\\\_key | product_code |
++========================================+==============+
+| "some_id#2024-04-30#\\\\x00\\\\x13\\\\x00\\\\xf3" | 1245427 |
++----------------------------------------+--------------+
+""",
+ " " * 12,
+ ),
+)
+
+# These changes should only be done on fresh copies of the .rst files
+# from googleapis-gen.
+if is_fresh_admin_docs_copy:
+ # Change the subpackage for clients with overridden internal methods in them
+ # from service to overlay.service.
+ s.replace(
+ "docs/admin_client/bigtable_table_admin.rst",
+ r"^\.\. automodule:: google\.cloud\.bigtable_admin_v2\.services\.bigtable_table_admin$",
+ ".. automodule:: google.cloud.bigtable_admin_v2.overlay.services.bigtable_table_admin"
+ )
+
+ # Add overlay types to types documentation
+ s.replace(
+ "docs/admin_client/types_.rst",
+ r"""(\.\. automodule:: google\.cloud\.bigtable_admin_v2\.types
+ :members:
+ :show-inheritance:)
+""",
+ r"""\1
+
+.. automodule:: google.cloud.bigtable_admin_v2.overlay.types
+ :members:
+ :show-inheritance:
+"""
+ )
+
+# These changes should only be done on a fresh copy of table.py
+# from googleapis-gen.
+if is_fresh_admin_v2_copy:
+ # Add the oneof_message import into table.py for GcRule
+ s.replace(
+ "google/cloud/bigtable_admin_v2/types/table.py",
+ r"^(from google\.cloud\.bigtable_admin_v2\.types import .+)$",
+ r"""\1
+from google.cloud.bigtable_admin_v2.utils import oneof_message""",
+ )
+
+ # Re-subclass GcRule in table.py
+ s.replace(
+ "google/cloud/bigtable_admin_v2/types/table.py",
+ r"class GcRule\(proto\.Message\)\:",
+ "class GcRule(oneof_message.OneofMessage):",
+ )
diff --git a/.librarian/generator-input/noxfile.py b/.librarian/generator-input/noxfile.py
new file mode 100644
index 000000000..d1176966e
--- /dev/null
+++ b/.librarian/generator-input/noxfile.py
@@ -0,0 +1,569 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright 2024 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
+#
+# https://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.
+
+# Generated by synthtool. DO NOT EDIT!
+
+from __future__ import absolute_import
+
+import os
+import pathlib
+import re
+import shutil
+from typing import Dict, List
+import warnings
+
+import nox
+
+FLAKE8_VERSION = "flake8==6.1.0"
+BLACK_VERSION = "black[jupyter]==23.3.0"
+ISORT_VERSION = "isort==5.11.0"
+LINT_PATHS = ["google", "tests", "noxfile.py", "setup.py"]
+
+DEFAULT_PYTHON_VERSION = "3.13"
+
+UNIT_TEST_PYTHON_VERSIONS: List[str] = [
+ "3.7",
+ "3.8",
+ "3.9",
+ "3.10",
+ "3.11",
+ "3.12",
+ "3.13",
+ "3.14",
+]
+UNIT_TEST_STANDARD_DEPENDENCIES = [
+ "mock",
+ "asyncmock",
+ "pytest",
+ "pytest-cov",
+ "pytest-asyncio",
+ BLACK_VERSION,
+ "autoflake",
+]
+UNIT_TEST_EXTERNAL_DEPENDENCIES: List[str] = []
+UNIT_TEST_LOCAL_DEPENDENCIES: List[str] = []
+UNIT_TEST_DEPENDENCIES: List[str] = []
+UNIT_TEST_EXTRAS: List[str] = []
+UNIT_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {}
+
+SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.10", "3.14"]
+SYSTEM_TEST_STANDARD_DEPENDENCIES: List[str] = [
+ "mock",
+ "pytest",
+ "google-cloud-testutils",
+]
+SYSTEM_TEST_EXTERNAL_DEPENDENCIES: List[str] = [
+ "pytest-asyncio==0.21.2",
+ BLACK_VERSION,
+ "pyyaml==6.0.2",
+]
+SYSTEM_TEST_LOCAL_DEPENDENCIES: List[str] = []
+SYSTEM_TEST_DEPENDENCIES: List[str] = []
+SYSTEM_TEST_EXTRAS: List[str] = []
+SYSTEM_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {}
+
+CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute()
+
+# 'docfx' is excluded since it only needs to run in 'docs-presubmit'
+nox.options.sessions = [
+ "unit-3.10",
+ "unit-3.11",
+ "unit-3.12",
+ "unit-3.13",
+ "unit-3.14",
+ "system_emulated",
+ "system",
+ "mypy",
+ "cover",
+ "lint",
+ "lint_setup_py",
+ "blacken",
+ "docs",
+ "format",
+]
+
+# Error if a python version is missing
+nox.options.error_on_missing_interpreters = True
+
+
+@nox.session(python=DEFAULT_PYTHON_VERSION)
+def lint(session):
+ """Run linters.
+
+ Returns a failure if the linters find linting errors or sufficiently
+ serious code quality issues.
+ """
+ session.install(FLAKE8_VERSION, BLACK_VERSION)
+ session.run(
+ "black",
+ "--check",
+ *LINT_PATHS,
+ )
+ session.run("flake8", "google", "tests")
+
+
+@nox.session(python=DEFAULT_PYTHON_VERSION)
+def blacken(session):
+ """Run black. Format code to uniform standard."""
+ session.install(BLACK_VERSION)
+ session.run(
+ "black",
+ *LINT_PATHS,
+ )
+
+
+@nox.session(python=DEFAULT_PYTHON_VERSION)
+def format(session):
+ """
+ Run isort to sort imports. Then run black
+ to format code to uniform standard.
+ """
+ session.install(BLACK_VERSION, ISORT_VERSION)
+ # Use the --fss option to sort imports using strict alphabetical order.
+ # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections
+ session.run(
+ "isort",
+ "--fss",
+ *LINT_PATHS,
+ )
+ session.run(
+ "black",
+ *LINT_PATHS,
+ )
+
+
+@nox.session(python=DEFAULT_PYTHON_VERSION)
+def mypy(session):
+ """Verify type hints are mypy compatible."""
+ session.install("-e", ".")
+ session.install(
+ "mypy", "types-setuptools", "types-protobuf", "types-mock", "types-requests"
+ )
+ session.install("google-cloud-testutils")
+ session.run("mypy", "-p", "google.cloud.bigtable.data")
+
+
+@nox.session(python=DEFAULT_PYTHON_VERSION)
+def lint_setup_py(session):
+ """Verify that setup.py is valid (including RST check)."""
+ session.install("setuptools", "docutils", "pygments")
+ session.run("python", "setup.py", "check", "--restructuredtext", "--strict")
+
+
+def install_unittest_dependencies(session, *constraints):
+ standard_deps = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_DEPENDENCIES
+ session.install(*standard_deps, *constraints)
+
+ if UNIT_TEST_EXTERNAL_DEPENDENCIES:
+ warnings.warn(
+ "'unit_test_external_dependencies' is deprecated. Instead, please "
+ "use 'unit_test_dependencies' or 'unit_test_local_dependencies'.",
+ DeprecationWarning,
+ )
+ session.install(*UNIT_TEST_EXTERNAL_DEPENDENCIES, *constraints)
+
+ if UNIT_TEST_LOCAL_DEPENDENCIES:
+ session.install(*UNIT_TEST_LOCAL_DEPENDENCIES, *constraints)
+
+ if UNIT_TEST_EXTRAS_BY_PYTHON:
+ extras = UNIT_TEST_EXTRAS_BY_PYTHON.get(session.python, [])
+ elif UNIT_TEST_EXTRAS:
+ extras = UNIT_TEST_EXTRAS
+ else:
+ extras = []
+
+ if extras:
+ session.install("-e", f".[{','.join(extras)}]", *constraints)
+ else:
+ session.install("-e", ".", *constraints)
+
+
+@nox.session(python=UNIT_TEST_PYTHON_VERSIONS)
+@nox.parametrize(
+ "protobuf_implementation",
+ ["python", "upb", "cpp"],
+)
+def unit(session, protobuf_implementation):
+ # Install all test dependencies, then install this package in-place.
+ py_version = tuple([int(v) for v in session.python.split(".")])
+ if protobuf_implementation == "cpp" and py_version >= (3, 11):
+ session.skip("cpp implementation is not supported in python 3.11+")
+
+ constraints_path = str(
+ CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt"
+ )
+ install_unittest_dependencies(session, "-c", constraints_path)
+
+ # TODO(https://github.com/googleapis/synthtool/issues/1976):
+ # Remove the 'cpp' implementation once support for Protobuf 3.x is dropped.
+ # The 'cpp' implementation requires Protobuf<4.
+ if protobuf_implementation == "cpp":
+ session.install("protobuf<4")
+
+ # Run py.test against the unit tests.
+ session.run(
+ "py.test",
+ "--quiet",
+ f"--junitxml=unit_{session.python}_sponge_log.xml",
+ "--cov=google",
+ "--cov=tests/unit",
+ "--cov-append",
+ "--cov-config=.coveragerc",
+ "--cov-report=",
+ "--cov-fail-under=0",
+ os.path.join("tests", "unit"),
+ *session.posargs,
+ env={
+ "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation,
+ },
+ )
+
+
+def install_systemtest_dependencies(session, *constraints):
+ # Use pre-release gRPC for system tests.
+ # Exclude version 1.52.0rc1 which has a known issue.
+ # See https://github.com/grpc/grpc/issues/32163
+ session.install("--pre", "grpcio!=1.52.0rc1")
+
+ session.install(*SYSTEM_TEST_STANDARD_DEPENDENCIES, *constraints)
+
+ if SYSTEM_TEST_EXTERNAL_DEPENDENCIES:
+ session.install(*SYSTEM_TEST_EXTERNAL_DEPENDENCIES, *constraints)
+
+ if SYSTEM_TEST_LOCAL_DEPENDENCIES:
+ session.install("-e", *SYSTEM_TEST_LOCAL_DEPENDENCIES, *constraints)
+
+ if SYSTEM_TEST_DEPENDENCIES:
+ session.install("-e", *SYSTEM_TEST_DEPENDENCIES, *constraints)
+
+ if SYSTEM_TEST_EXTRAS_BY_PYTHON:
+ extras = SYSTEM_TEST_EXTRAS_BY_PYTHON.get(session.python, [])
+ elif SYSTEM_TEST_EXTRAS:
+ extras = SYSTEM_TEST_EXTRAS
+ else:
+ extras = []
+
+ if extras:
+ session.install("-e", f".[{','.join(extras)}]", *constraints)
+ else:
+ session.install("-e", ".", *constraints)
+
+
+@nox.session(python=DEFAULT_PYTHON_VERSION)
+def system_emulated(session):
+ import subprocess
+ import signal
+
+ try:
+ subprocess.call(["gcloud", "--version"])
+ except OSError:
+ session.skip("gcloud not found but required for emulator support")
+
+ # Currently, CI/CD doesn't have beta component of gcloud.
+ subprocess.call(["gcloud", "components", "install", "beta", "bigtable"])
+
+ hostport = "localhost:8789"
+ session.env["BIGTABLE_EMULATOR_HOST"] = hostport
+
+ p = subprocess.Popen(
+ ["gcloud", "beta", "emulators", "bigtable", "start", "--host-port", hostport]
+ )
+
+ try:
+ system(session)
+ finally:
+ # Stop Emulator
+ os.killpg(os.getpgid(p.pid), signal.SIGKILL)
+
+
+@nox.session(python=SYSTEM_TEST_PYTHON_VERSIONS)
+@nox.parametrize("client_type", ["async", "sync", "legacy"])
+def conformance(session, client_type):
+ # install dependencies
+ constraints_path = str(
+ CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt"
+ )
+ install_unittest_dependencies(session, "-c", constraints_path)
+ with session.chdir("test_proxy"):
+ # download the conformance test suite
+ session.run(
+ "bash",
+ "-e",
+ "run_tests.sh",
+ external=True,
+ env={"CLIENT_TYPE": client_type},
+ )
+
+
+@nox.session(python=SYSTEM_TEST_PYTHON_VERSIONS)
+def system(session):
+ """Run the system test suite."""
+ constraints_path = str(
+ CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt"
+ )
+ system_test_path = os.path.join("tests", "system.py")
+ system_test_folder_path = os.path.join("tests", "system")
+
+ # Check the value of `RUN_SYSTEM_TESTS` env var. It defaults to true.
+ if os.environ.get("RUN_SYSTEM_TESTS", "true") == "false":
+ session.skip("RUN_SYSTEM_TESTS is set to false, skipping")
+ # Install pyopenssl for mTLS testing.
+ if os.environ.get("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true":
+ session.install("pyopenssl")
+
+ system_test_exists = os.path.exists(system_test_path)
+ system_test_folder_exists = os.path.exists(system_test_folder_path)
+ # Sanity check: only run tests if found.
+ if not system_test_exists and not system_test_folder_exists:
+ session.skip("System tests were not found")
+
+ install_systemtest_dependencies(session, "-c", constraints_path)
+
+ # Run py.test against the system tests.
+ if system_test_exists:
+ session.run(
+ "py.test",
+ "--quiet",
+ f"--junitxml=system_{session.python}_sponge_log.xml",
+ system_test_path,
+ *session.posargs,
+ )
+ if system_test_folder_exists:
+ session.run(
+ "py.test",
+ "--quiet",
+ f"--junitxml=system_{session.python}_sponge_log.xml",
+ system_test_folder_path,
+ *session.posargs,
+ )
+
+
+@nox.session(python=DEFAULT_PYTHON_VERSION)
+def cover(session):
+ """Run the final coverage report.
+
+ This outputs the coverage report aggregating coverage from the unit
+ test runs (not system test runs), and then erases coverage data.
+ """
+ session.install("coverage", "pytest-cov")
+ session.run("coverage", "report", "--show-missing", "--fail-under=99")
+
+ session.run("coverage", "erase")
+
+
+@nox.session(python="3.10")
+def docs(session):
+ """Build the docs for this library."""
+
+ session.install("-e", ".")
+ session.install(
+ # We need to pin to specific versions of the `sphinxcontrib-*` packages
+ # which still support sphinx 4.x.
+ # See https://github.com/googleapis/sphinx-docfx-yaml/issues/344
+ # and https://github.com/googleapis/sphinx-docfx-yaml/issues/345.
+ "sphinxcontrib-applehelp==1.0.4",
+ "sphinxcontrib-devhelp==1.0.2",
+ "sphinxcontrib-htmlhelp==2.0.1",
+ "sphinxcontrib-qthelp==1.0.3",
+ "sphinxcontrib-serializinghtml==1.1.5",
+ "sphinx==4.5.0",
+ "alabaster",
+ "recommonmark",
+ )
+
+ shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True)
+ session.run(
+ "sphinx-build",
+ "-W", # warnings as errors
+ "-T", # show full traceback on exception
+ "-N", # no colors
+ "-b",
+ "html",
+ "-d",
+ os.path.join("docs", "_build", "doctrees", ""),
+ os.path.join("docs", ""),
+ os.path.join("docs", "_build", "html", ""),
+ )
+
+
+@nox.session(python="3.10")
+def docfx(session):
+ """Build the docfx yaml files for this library."""
+
+ session.install("-e", ".")
+ session.install(
+ # We need to pin to specific versions of the `sphinxcontrib-*` packages
+ # which still support sphinx 4.x.
+ # See https://github.com/googleapis/sphinx-docfx-yaml/issues/344
+ # and https://github.com/googleapis/sphinx-docfx-yaml/issues/345.
+ "sphinxcontrib-applehelp==1.0.4",
+ "sphinxcontrib-devhelp==1.0.2",
+ "sphinxcontrib-htmlhelp==2.0.1",
+ "sphinxcontrib-qthelp==1.0.3",
+ "sphinxcontrib-serializinghtml==1.1.5",
+ "gcp-sphinx-docfx-yaml",
+ "alabaster",
+ "recommonmark",
+ )
+
+ shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True)
+ session.run(
+ "sphinx-build",
+ "-T", # show full traceback on exception
+ "-N", # no colors
+ "-D",
+ (
+ "extensions=sphinx.ext.autodoc,"
+ "sphinx.ext.autosummary,"
+ "docfx_yaml.extension,"
+ "sphinx.ext.intersphinx,"
+ "sphinx.ext.coverage,"
+ "sphinx.ext.napoleon,"
+ "sphinx.ext.todo,"
+ "sphinx.ext.viewcode,"
+ "recommonmark"
+ ),
+ "-b",
+ "html",
+ "-d",
+ os.path.join("docs", "_build", "doctrees", ""),
+ os.path.join("docs", ""),
+ os.path.join("docs", "_build", "html", ""),
+ )
+ # Customization: Add extra sections to the table of contents for the Classic vs Async clients
+ session.install("pyyaml")
+ session.run("python", "docs/scripts/patch_devsite_toc.py")
+
+
+@nox.session(python="3.14")
+@nox.parametrize(
+ "protobuf_implementation",
+ ["python", "upb", "cpp"],
+)
+def prerelease_deps(session, protobuf_implementation):
+ """Run all tests with prerelease versions of dependencies installed."""
+
+ py_version = tuple([int(v) for v in session.python.split(".")])
+ if protobuf_implementation == "cpp" and py_version >= (3, 11):
+ session.skip("cpp implementation is not supported in python 3.11+")
+
+ # Install all dependencies
+ session.install("-e", ".[all, tests, tracing]")
+ unit_deps_all = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_EXTERNAL_DEPENDENCIES
+ session.install(*unit_deps_all)
+ system_deps_all = (
+ SYSTEM_TEST_STANDARD_DEPENDENCIES + SYSTEM_TEST_EXTERNAL_DEPENDENCIES
+ )
+ session.install(*system_deps_all)
+
+ # Because we test minimum dependency versions on the minimum Python
+ # version, the first version we test with in the unit tests sessions has a
+ # constraints file containing all dependencies and extras.
+ with open(
+ CURRENT_DIRECTORY
+ / "testing"
+ / f"constraints-{UNIT_TEST_PYTHON_VERSIONS[0]}.txt",
+ encoding="utf-8",
+ ) as constraints_file:
+ constraints_text = constraints_file.read()
+
+ # Ignore leading whitespace and comment lines.
+ constraints_deps = [
+ match.group(1)
+ for match in re.finditer(
+ r"^\s*(\S+)(?===\S+)", constraints_text, flags=re.MULTILINE
+ )
+ ]
+
+ session.install(*constraints_deps)
+
+ prerel_deps = [
+ "protobuf",
+ # dependency of grpc
+ "six",
+ "grpc-google-iam-v1",
+ "googleapis-common-protos",
+ "grpcio",
+ "grpcio-status",
+ "google-api-core",
+ "google-auth",
+ "proto-plus",
+ "google-cloud-testutils",
+ # dependencies of google-cloud-testutils"
+ "click",
+ ]
+
+ for dep in prerel_deps:
+ session.install("--pre", "--no-deps", "--upgrade", dep)
+
+ # Remaining dependencies
+ other_deps = [
+ "requests",
+ "cryptography",
+ ]
+ session.install(*other_deps)
+
+ # Print out prerelease package versions
+ session.run(
+ "python", "-c", "import google.protobuf; print(google.protobuf.__version__)"
+ )
+ session.run("python", "-c", "import grpc; print(grpc.__version__)")
+ session.run("python", "-c", "import google.auth; print(google.auth.__version__)")
+
+ session.run(
+ "py.test",
+ "tests/unit",
+ env={
+ "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation,
+ },
+ )
+
+ system_test_path = os.path.join("tests", "system.py")
+ system_test_folder_path = os.path.join("tests", "system")
+
+ # Only run system tests if found.
+ if os.path.exists(system_test_path):
+ session.run(
+ "py.test",
+ "--verbose",
+ f"--junitxml=system_{session.python}_sponge_log.xml",
+ system_test_path,
+ *session.posargs,
+ env={
+ "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation,
+ },
+ )
+ if os.path.exists(system_test_folder_path):
+ session.run(
+ "py.test",
+ "--verbose",
+ f"--junitxml=system_{session.python}_sponge_log.xml",
+ system_test_folder_path,
+ *session.posargs,
+ env={
+ "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": protobuf_implementation,
+ },
+ )
+
+
+@nox.session(python="3.10")
+def generate_sync(session):
+ """
+ Re-generate sync files for the library from CrossSync-annotated async source
+ """
+ session.install(BLACK_VERSION)
+ session.install("autoflake")
+ session.run("python", ".cross_sync/generate.py", ".")
diff --git a/.librarian/generator-input/setup.py b/.librarian/generator-input/setup.py
new file mode 100644
index 000000000..fd8062970
--- /dev/null
+++ b/.librarian/generator-input/setup.py
@@ -0,0 +1,100 @@
+# Copyright 2018 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 io
+import os
+
+import setuptools
+
+
+package_root = os.path.abspath(os.path.dirname(__file__))
+
+# Package metadata.
+
+name = "google-cloud-bigtable"
+description = "Google Cloud Bigtable API client library"
+
+version = {}
+with open(os.path.join(package_root, "google/cloud/bigtable/gapic_version.py")) as fp:
+ exec(fp.read(), version)
+version = version["__version__"]
+
+
+# Should be one of:
+# 'Development Status :: 3 - Alpha'
+# 'Development Status :: 4 - Beta'
+# 'Development Status :: 5 - Production/Stable'
+release_status = "Development Status :: 5 - Production/Stable"
+dependencies = [
+ "google-api-core[grpc] >= 2.17.0, <3.0.0",
+ "google-cloud-core >= 1.4.4, <3.0.0",
+ "google-auth >= 2.23.0, <3.0.0,!=2.24.0,!=2.25.0",
+ "grpc-google-iam-v1 >= 0.12.4, <1.0.0",
+ "proto-plus >= 1.22.3, <2.0.0",
+ "proto-plus >= 1.25.0, <2.0.0; python_version>='3.13'",
+ "protobuf>=3.20.2,<7.0.0,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5",
+ "google-crc32c>=1.5.0, <2.0.0dev",
+]
+extras = {"libcst": "libcst >= 0.2.5"}
+
+
+# Setup boilerplate below this line.
+
+package_root = os.path.abspath(os.path.dirname(__file__))
+
+readme_filename = os.path.join(package_root, "README.rst")
+with io.open(readme_filename, encoding="utf-8") as readme_file:
+ readme = readme_file.read()
+
+# Only include packages under the 'google' namespace. Do not include tests,
+# benchmarks, etc.
+packages = [
+ package
+ for package in setuptools.find_namespace_packages()
+ if package.startswith("google")
+]
+
+setuptools.setup(
+ name=name,
+ version=version,
+ description=description,
+ long_description=readme,
+ author="Google LLC",
+ author_email="googleapis-packages@google.com",
+ license="Apache 2.0",
+ url="https://github.com/googleapis/python-bigtable",
+ classifiers=[
+ release_status,
+ "Intended Audience :: Developers",
+ "License :: OSI Approved :: Apache Software License",
+ "Programming Language :: Python",
+ "Programming Language :: Python :: 3.7",
+ "Programming Language :: Python :: 3.8",
+ "Programming Language :: Python :: 3.9",
+ "Programming Language :: Python :: 3.10",
+ "Programming Language :: Python :: 3.11",
+ "Programming Language :: Python :: 3.12",
+ "Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
+ "Operating System :: OS Independent",
+ "Topic :: Internet",
+ ],
+ platforms="Posix; MacOS X; Windows",
+ packages=packages,
+ install_requires=dependencies,
+ extras_require=extras,
+ python_requires=">=3.7",
+ include_package_data=True,
+ zip_safe=False,
+)
diff --git a/.librarian/state.yaml b/.librarian/state.yaml
new file mode 100644
index 000000000..71d0e465d
--- /dev/null
+++ b/.librarian/state.yaml
@@ -0,0 +1,40 @@
+image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:b8058df4c45e9a6e07f6b4d65b458d0d059241dd34c814f151c8bf6b89211209
+libraries:
+ - id: google-cloud-bigtable
+ version: 2.35.0
+ last_generated_commit: 9637e50bc0ff6a5e8944980aaf6a2b7f34a90910
+ apis:
+ - path: google/bigtable/v2
+ service_config: bigtable_v2.yaml
+ - path: google/bigtable/admin/v2
+ service_config: bigtableadmin_v2.yaml
+ source_roots:
+ - .
+ preserve_regex: []
+ remove_regex:
+ - ^.pre-commit-config.yaml
+ - ^.repo-metadata.json
+ - ^.trampolinerc
+ - ^docs/admin_client/bigtable
+ - ^docs/admin_client/services_.rst
+ - ^docs/admin_client/types_.rst
+ - ^docs/summary_overview.md
+ - ^google/cloud/bigtable_v2
+ - ^google/cloud/bigtable_admin/
+ - ^google/cloud/bigtable_admin_v2/services
+ - ^google/cloud/bigtable_admin_v2/types
+ - ^google/cloud/bigtable_admin_v2/__init__.py
+ - ^google/cloud/bigtable_admin_v2/gapic
+ - ^google/cloud/bigtable_admin_v2/py.typed
+ - ^samples/AUTHORING_GUIDE.md
+ - ^samples/CONTRIBUTING.md
+ - ^samples/generated_samples
+ - ^tests/unit/gapic
+ - ^noxfile.py
+ - ^scripts/fixup_bigtable
+ - ^setup.py
+ - ^SECURITY.md
+ - ^tests/__init__.py
+ - ^tests/unit/__init__.py
+ - ^tests/unit/gapic
+ tag_format: v{version}
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 46d237160..1d74695f7 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,4 +1,4 @@
-# Copyright 2021 Google LLC
+# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -22,10 +22,10 @@ repos:
- id: end-of-file-fixer
- id: check-yaml
- repo: https://github.com/psf/black
- rev: 22.3.0
+ rev: 23.7.0
hooks:
- id: black
-- repo: https://gitlab.com/pycqa/flake8
- rev: 3.9.2
+- repo: https://github.com/pycqa/flake8
+ rev: 6.1.0
hooks:
- id: flake8
diff --git a/.repo-metadata.json b/.repo-metadata.json
index 3c65ac669..9de4b5f92 100644
--- a/.repo-metadata.json
+++ b/.repo-metadata.json
@@ -75,6 +75,6 @@
}
],
"default_version": "v2",
- "codeowner_team": "@googleapis/api-bigtable",
+ "codeowner_team": "@googleapis/api-bigtable @googleapis/api-bigtable-partners",
"api_shortname": "bigtable"
}
diff --git a/.trampolinerc b/.trampolinerc
index 0eee72ab6..008015237 100644
--- a/.trampolinerc
+++ b/.trampolinerc
@@ -1,4 +1,4 @@
-# Copyright 2020 Google LLC
+# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -12,8 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# Template for .trampolinerc
-
# Add required env vars here.
required_envvars+=(
)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index be1a397d8..cbb707694 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,442 @@
[1]: https://pypi.org/project/google-cloud-bigtable/#history
+## [2.35.0](https://github.com/googleapis/python-bigtable/compare/v2.34.0...v2.35.0) (2025-12-16)
+
+
+### Features
+
+* support mTLS certificates when available (#1249) ([ca20219cf45305de25dfb715f69dd63bce9981b7](https://github.com/googleapis/python-bigtable/commit/ca20219cf45305de25dfb715f69dd63bce9981b7))
+* add basic interceptor to client (#1206) ([6561cfac605ba7c5b3f750c3bdca9108e517ba77](https://github.com/googleapis/python-bigtable/commit/6561cfac605ba7c5b3f750c3bdca9108e517ba77))
+* add PeerInfo proto in Bigtable API ([72dfdc440c22db0f4c372e6f11a9f7dc83fed350](https://github.com/googleapis/python-bigtable/commit/72dfdc440c22db0f4c372e6f11a9f7dc83fed350))
+* Add Type API updates needed to support structured keys in materialized views ([72dfdc440c22db0f4c372e6f11a9f7dc83fed350](https://github.com/googleapis/python-bigtable/commit/72dfdc440c22db0f4c372e6f11a9f7dc83fed350))
+* Add encodings for STRUCT and the Timestamp type ([72dfdc440c22db0f4c372e6f11a9f7dc83fed350](https://github.com/googleapis/python-bigtable/commit/72dfdc440c22db0f4c372e6f11a9f7dc83fed350))
+
+
+### Bug Fixes
+
+* async client uses fixed grace period (#1236) ([544db1cd7af876298b8637f495b6c7b2a0bcf16c](https://github.com/googleapis/python-bigtable/commit/544db1cd7af876298b8637f495b6c7b2a0bcf16c))
+* re-export AddToCell for consistency (#1241) ([2a5baf11d30dc383a7b48d5f43b6cbb6160782e3](https://github.com/googleapis/python-bigtable/commit/2a5baf11d30dc383a7b48d5f43b6cbb6160782e3))
+* retry cancelled errors (#1235) ([e3fd5d8668303db4ed35e9bf6be48b46954f9d67](https://github.com/googleapis/python-bigtable/commit/e3fd5d8668303db4ed35e9bf6be48b46954f9d67))
+* Add ReadRows/SampleRowKeys bindings for materialized views ([72dfdc440c22db0f4c372e6f11a9f7dc83fed350](https://github.com/googleapis/python-bigtable/commit/72dfdc440c22db0f4c372e6f11a9f7dc83fed350))
+* Deprecate credentials_file argument ([72dfdc440c22db0f4c372e6f11a9f7dc83fed350](https://github.com/googleapis/python-bigtable/commit/72dfdc440c22db0f4c372e6f11a9f7dc83fed350))
+
+## [2.34.0](https://github.com/googleapis/python-bigtable/compare/v2.33.0...v2.34.0) (2025-10-16)
+
+
+### Features
+
+* Add support for Python 3.14 ([#1217](https://github.com/googleapis/python-bigtable/issues/1217)) ([263332a](https://github.com/googleapis/python-bigtable/commit/263332af71a229cb4fa598008a708137086a6f67))
+
+## [2.33.0](https://github.com/googleapis/python-bigtable/compare/v2.32.0...v2.33.0) (2025-10-06)
+
+
+### Features
+
+* Add support for Proto and Enum types ([#1202](https://github.com/googleapis/python-bigtable/issues/1202)) ([34ceb86](https://github.com/googleapis/python-bigtable/commit/34ceb86007db08d453fa25cca4968d5b498ffcd6))
+* Expose universe_domain for tpc ([#1150](https://github.com/googleapis/python-bigtable/issues/1150)) ([451fd97](https://github.com/googleapis/python-bigtable/commit/451fd97e435218ffed47d39423680ffc4feccac4))
+
+
+### Bug Fixes
+
+* Fix instance registration cleanup on early iterator termination ([#1216](https://github.com/googleapis/python-bigtable/issues/1216)) ([bbfd746](https://github.com/googleapis/python-bigtable/commit/bbfd746c61a6362efa42c7899ec3e34ceb541c83))
+* Refactor channel refresh ([#1174](https://github.com/googleapis/python-bigtable/issues/1174)) ([6fa3008](https://github.com/googleapis/python-bigtable/commit/6fa30084058bc34d4487d1fee5c87d7795ff167a))
+
+## [2.32.0](https://github.com/googleapis/python-bigtable/compare/v2.31.0...v2.32.0) (2025-08-01)
+
+
+### Features
+
+* Add Idempotency to Cloud Bigtable MutateRowsRequest API ([#1143](https://github.com/googleapis/python-bigtable/issues/1143)) ([c3e3eb0](https://github.com/googleapis/python-bigtable/commit/c3e3eb0e4ce44ece72b150dc5822846627074fba))
+* Add support for AddToCell in Data Client ([#1147](https://github.com/googleapis/python-bigtable/issues/1147)) ([1a5b4b5](https://github.com/googleapis/python-bigtable/commit/1a5b4b514cadae5c83d61296314285d3774992c5))
+* Implement SQL support in test proxy ([#1106](https://github.com/googleapis/python-bigtable/issues/1106)) ([7a91bbf](https://github.com/googleapis/python-bigtable/commit/7a91bbfb9df23f7e93c40b88648840342af6f16f))
+* Modernized Bigtable Admin Client featuring selective GAPIC generation ([#1177](https://github.com/googleapis/python-bigtable/issues/1177)) ([58e7d37](https://github.com/googleapis/python-bigtable/commit/58e7d3782df6b13a42af053263afc575222a6b83))
+
+## [2.31.0](https://github.com/googleapis/python-bigtable/compare/v2.30.1...v2.31.0) (2025-05-22)
+
+
+### Features
+
+* Add deletion_protection support for LVs ([#1108](https://github.com/googleapis/python-bigtable/issues/1108)) ([c6d384d](https://github.com/googleapis/python-bigtable/commit/c6d384d4a104c182326e22dc3f10b7b905780dee))
+* Support authorized views ([#1034](https://github.com/googleapis/python-bigtable/issues/1034)) ([97a0198](https://github.com/googleapis/python-bigtable/commit/97a019833d82e617769c56761aa5548d3ab896b9))
+* Throw better error on invalid metadata response ([#1107](https://github.com/googleapis/python-bigtable/issues/1107)) ([2642317](https://github.com/googleapis/python-bigtable/commit/2642317077b723ca8fd62aa86322b524868c2c4d))
+
+
+### Bug Fixes
+
+* Re-add py-typed file for bigtable package ([#1085](https://github.com/googleapis/python-bigtable/issues/1085)) ([0c322c7](https://github.com/googleapis/python-bigtable/commit/0c322c79ecbe4cde3e79d8e83ac655a978d07877))
+
+## [2.30.1](https://github.com/googleapis/python-bigtable/compare/v2.30.0...v2.30.1) (2025-04-17)
+
+
+### Bug Fixes
+
+* Populate SQL app_profile_id header even when it is unset ([#1109](https://github.com/googleapis/python-bigtable/issues/1109)) ([17b75bd](https://github.com/googleapis/python-bigtable/commit/17b75bd746cb0a616f64a05eb0ed72b46de28a17))
+
+## [2.30.0](https://github.com/googleapis/python-bigtable/compare/v2.29.0...v2.30.0) (2025-03-18)
+
+
+### Features
+
+* Update ExecuteQuery to use Prepare ([#1100](https://github.com/googleapis/python-bigtable/issues/1100)) ([8a7abc1](https://github.com/googleapis/python-bigtable/commit/8a7abc1e9c34a9122b2d648e8a358a7097ed3a5d))
+
+
+### Bug Fixes
+
+* Allow protobuf 6.x ([#1092](https://github.com/googleapis/python-bigtable/issues/1092)) ([1015fa8](https://github.com/googleapis/python-bigtable/commit/1015fa83c505487f09820e3a37f76690bd00ab5d))
+* Remove setup.cfg configuration for creating universal wheels ([#1097](https://github.com/googleapis/python-bigtable/issues/1097)) ([95f4b82](https://github.com/googleapis/python-bigtable/commit/95f4b8233cba2a18633e64c5e0bc177e23767a83))
+
+## [2.29.0](https://github.com/googleapis/python-bigtable/compare/v2.28.1...v2.29.0) (2025-02-26)
+
+
+### Features
+
+* Add support for array and float32 SQL query params ([#1078](https://github.com/googleapis/python-bigtable/issues/1078)) ([89b8da8](https://github.com/googleapis/python-bigtable/commit/89b8da8a445aeb08854d9fa77cbc0e4fc042c87f))
+
+
+### Bug Fixes
+
+* Grpc channel refresh ([#1087](https://github.com/googleapis/python-bigtable/issues/1087)) ([f44b36b](https://github.com/googleapis/python-bigtable/commit/f44b36bf51e3e4e3b8a774f96e682d3f1f8d4b16))
+
+## [2.28.1](https://github.com/googleapis/python-bigtable/compare/v2.28.0...v2.28.1) (2025-01-17)
+
+
+### Bug Fixes
+
+* Allow empty headers for btql routing ([#1072](https://github.com/googleapis/python-bigtable/issues/1072)) ([e7ecfeb](https://github.com/googleapis/python-bigtable/commit/e7ecfeb8984a45c880d9483305964fff347eb4b8))
+
+## [2.28.0](https://github.com/googleapis/python-bigtable/compare/v2.27.0...v2.28.0) (2025-01-08)
+
+
+### Features
+
+* Add generated sync client ([#1017](https://github.com/googleapis/python-bigtable/issues/1017)) ([f974823](https://github.com/googleapis/python-bigtable/commit/f974823bf8a74c2f8b1bc69997b13bc1acaf8bef))
+
+## [2.27.0](https://github.com/googleapis/python-bigtable/compare/v2.26.0...v2.27.0) (2024-11-12)
+
+
+### Features
+
+* Add support for Cloud Bigtable Node Scaling Factor for CBT Clusters ([#1023](https://github.com/googleapis/python-bigtable/issues/1023)) ([0809c6a](https://github.com/googleapis/python-bigtable/commit/0809c6ac274e909103ad160a8bcab95f8bb46f31))
+* Surface `retry` param to `Table.read_row` api ([#982](https://github.com/googleapis/python-bigtable/issues/982)) ([a8286d2](https://github.com/googleapis/python-bigtable/commit/a8286d2a510f654f9c270c3c761c02e4ab3817d4))
+
+
+### Bug Fixes
+
+* Registering duplicate instance ([#1033](https://github.com/googleapis/python-bigtable/issues/1033)) ([2bca8fb](https://github.com/googleapis/python-bigtable/commit/2bca8fb220eeb1906fc6a3cf1f879f3d41fbbff8))
+
+## [2.26.0](https://github.com/googleapis/python-bigtable/compare/v2.25.0...v2.26.0) (2024-08-12)
+
+
+### Features
+
+* Add fields and the BackupType proto for Hot Backups ([#1010](https://github.com/googleapis/python-bigtable/issues/1010)) ([b95801f](https://github.com/googleapis/python-bigtable/commit/b95801ffa8081e0072232247fbc5879105c109a6))
+* Add MergeToCell to Mutation APIs ([f029a24](https://github.com/googleapis/python-bigtable/commit/f029a242e2b0e6020d0b87ef256a414194321fad))
+* Add min, max, hll aggregators and more types ([f029a24](https://github.com/googleapis/python-bigtable/commit/f029a242e2b0e6020d0b87ef256a414194321fad))
+* Async execute query client ([#1011](https://github.com/googleapis/python-bigtable/issues/1011)) ([45bc8c4](https://github.com/googleapis/python-bigtable/commit/45bc8c4a0fe567ce5e0126a1a70e7eb3dca93e92))
+
+
+### Bug Fixes
+
+* Use single routing metadata header ([#1005](https://github.com/googleapis/python-bigtable/issues/1005)) ([20eeb0a](https://github.com/googleapis/python-bigtable/commit/20eeb0a68d7b44d07a6d84bc7a7e040ad63bb96d))
+
+
+### Documentation
+
+* Add clarification around SQL timestamps ([#1012](https://github.com/googleapis/python-bigtable/issues/1012)) ([6e80190](https://github.com/googleapis/python-bigtable/commit/6e801900bbe9385d3b579b8c3327c87c3617d92f))
+* Corrected various type documentation ([f029a24](https://github.com/googleapis/python-bigtable/commit/f029a242e2b0e6020d0b87ef256a414194321fad))
+
+## [2.25.0](https://github.com/googleapis/python-bigtable/compare/v2.24.0...v2.25.0) (2024-07-18)
+
+
+### Features
+
+* Publish ProtoRows Message ([7ac8e14](https://github.com/googleapis/python-bigtable/commit/7ac8e142f99a6891b6bc286858f764def503e89a))
+* Publish the Cloud Bigtable ExecuteQuery API ([7ac8e14](https://github.com/googleapis/python-bigtable/commit/7ac8e142f99a6891b6bc286858f764def503e89a))
+
+
+### Bug Fixes
+
+* Allow protobuf 5.x ([7ac8e14](https://github.com/googleapis/python-bigtable/commit/7ac8e142f99a6891b6bc286858f764def503e89a))
+
+## [2.24.0](https://github.com/googleapis/python-bigtable/compare/v2.23.1...v2.24.0) (2024-06-11)
+
+
+### Features
+
+* Add String type with Utf8Raw encoding to Bigtable API ([#968](https://github.com/googleapis/python-bigtable/issues/968)) ([2a2bbfd](https://github.com/googleapis/python-bigtable/commit/2a2bbfdba6737c508ab1073d37fef680ca2a8c2f))
+* Improve async sharding ([#977](https://github.com/googleapis/python-bigtable/issues/977)) ([fd1f7da](https://github.com/googleapis/python-bigtable/commit/fd1f7dafd38f7f0e714a3384a27176f485523682))
+
+
+### Bug Fixes
+
+* **backup:** Backup name regex ([#970](https://github.com/googleapis/python-bigtable/issues/970)) ([6ef122a](https://github.com/googleapis/python-bigtable/commit/6ef122ad49f43e3a22cde5cb6fdaefd947670136))
+* Improve rowset revision ([#979](https://github.com/googleapis/python-bigtable/issues/979)) ([da27527](https://github.com/googleapis/python-bigtable/commit/da275279a7e619e4cd3e72b10ac629d6e0e1fe47))
+
+## [2.23.1](https://github.com/googleapis/python-bigtable/compare/v2.23.0...v2.23.1) (2024-04-15)
+
+
+### Bug Fixes
+
+* Use insecure grpc channel with emulator ([#946](https://github.com/googleapis/python-bigtable/issues/946)) ([aa31706](https://github.com/googleapis/python-bigtable/commit/aa3170663f9bd09d70c99d4e76c07f7f293ad935))
+
+## [2.23.0](https://github.com/googleapis/python-bigtable/compare/v2.22.0...v2.23.0) (2024-02-07)
+
+
+### Features
+
+* Add async data client preview ([7088e39](https://github.com/googleapis/python-bigtable/commit/7088e39c6bac10e5f830e8fa68e181412910ec5a))
+* Adding feature flags for routing cookie and retry info ([#905](https://github.com/googleapis/python-bigtable/issues/905)) ([1859e67](https://github.com/googleapis/python-bigtable/commit/1859e67961629663a8749eea849b5b005fcbc09f))
+
+
+### Bug Fixes
+
+* Fix `ValueError` in `test__validate_universe_domain` ([#929](https://github.com/googleapis/python-bigtable/issues/929)) ([aa76a5a](https://github.com/googleapis/python-bigtable/commit/aa76a5aaa349386d5972d96e1255389e30df8764))
+
+## [2.22.0](https://github.com/googleapis/python-bigtable/compare/v2.21.0...v2.22.0) (2023-12-12)
+
+
+### Features
+
+* Add support for Cloud Bigtable Request Priorities in App Profiles ([#871](https://github.com/googleapis/python-bigtable/issues/871)) ([a4d551e](https://github.com/googleapis/python-bigtable/commit/a4d551e34006202ee96a395a2107d7acdc5881de))
+* Add support for Python 3.12 ([#888](https://github.com/googleapis/python-bigtable/issues/888)) ([4f050aa](https://github.com/googleapis/python-bigtable/commit/4f050aa5aed9a9dcf209779d5c10e5de8e2ff19e))
+* Introduce compatibility with native namespace packages ([#893](https://github.com/googleapis/python-bigtable/issues/893)) ([d218f4e](https://github.com/googleapis/python-bigtable/commit/d218f4ebd4ed6705721dca9318df955b40b0d0ac))
+* Publish CopyBackup protos to external customers ([#855](https://github.com/googleapis/python-bigtable/issues/855)) ([4105df7](https://github.com/googleapis/python-bigtable/commit/4105df762f1318c49bba030063897f0c50e4daee))
+
+
+### Bug Fixes
+
+* Add feature flag for improved mutate rows throttling ([e5af359](https://github.com/googleapis/python-bigtable/commit/e5af3597f45fc4c094c59abca876374f5a866c1b))
+* Add lock to flow control ([#899](https://github.com/googleapis/python-bigtable/issues/899)) ([e4e63c7](https://github.com/googleapis/python-bigtable/commit/e4e63c7b5b91273b3aae04fda59cc5a21c848de2))
+* Mutations batcher race condition ([#896](https://github.com/googleapis/python-bigtable/issues/896)) ([fe58f61](https://github.com/googleapis/python-bigtable/commit/fe58f617c7364d7e99e2ec50abd5f080852bf033))
+* Require google-cloud-core 1.4.4 ([#866](https://github.com/googleapis/python-bigtable/issues/866)) ([09f8a46](https://github.com/googleapis/python-bigtable/commit/09f8a4667d8b68a9f2048ba1aa57db4f775a2c03))
+* Use `retry_async` instead of `retry` in async client ([597efd1](https://github.com/googleapis/python-bigtable/commit/597efd11d15f20549010b4301be4d9768326e6a2))
+
+
+### Documentation
+
+* Minor formatting ([e5af359](https://github.com/googleapis/python-bigtable/commit/e5af3597f45fc4c094c59abca876374f5a866c1b))
+
+## [2.21.0](https://github.com/googleapis/python-bigtable/compare/v2.20.0...v2.21.0) (2023-08-02)
+
+
+### Features
+
+* Add last_scanned_row_responses to FeatureFlags ([#845](https://github.com/googleapis/python-bigtable/issues/845)) ([14a6739](https://github.com/googleapis/python-bigtable/commit/14a673901f82fa247c8027730a0bba41e0ec4757))
+
+
+### Documentation
+
+* Minor formatting ([#851](https://github.com/googleapis/python-bigtable/issues/851)) ([5ebe231](https://github.com/googleapis/python-bigtable/commit/5ebe2312dab70210811fca68c6625d2546442afd))
+
+## [2.20.0](https://github.com/googleapis/python-bigtable/compare/v2.19.0...v2.20.0) (2023-07-17)
+
+
+### Features
+
+* Add experimental reverse scan for public preview ([d5720f8](https://github.com/googleapis/python-bigtable/commit/d5720f8f5b5a81572f31d40051b3ec0f1d104304))
+* Increase the maximum retention period for a Cloud Bigtable backup from 30 days to 90 days ([d5720f8](https://github.com/googleapis/python-bigtable/commit/d5720f8f5b5a81572f31d40051b3ec0f1d104304))
+
+
+### Bug Fixes
+
+* Add async context manager return types ([#828](https://github.com/googleapis/python-bigtable/issues/828)) ([475a160](https://github.com/googleapis/python-bigtable/commit/475a16072f3ad41357bdb765fff608a39141ec00))
+
+
+### Documentation
+
+* Fix formatting for reversed order field example ([#831](https://github.com/googleapis/python-bigtable/issues/831)) ([fddd0ba](https://github.com/googleapis/python-bigtable/commit/fddd0ba97155e112af92a98fd8f20e59b139d177))
+
+## [2.19.0](https://github.com/googleapis/python-bigtable/compare/v2.18.1...v2.19.0) (2023-06-08)
+
+
+### Features
+
+* Add ChangeStreamConfig to CreateTable and UpdateTable ([#786](https://github.com/googleapis/python-bigtable/issues/786)) ([cef70f2](https://github.com/googleapis/python-bigtable/commit/cef70f243541820225f86a520e0b2abd3a7354f7))
+
+
+### Bug Fixes
+
+* Add a callback function on flush_rows ([#796](https://github.com/googleapis/python-bigtable/issues/796)) ([589aa5d](https://github.com/googleapis/python-bigtable/commit/589aa5d04f6b5a2bd310d0bf06aeb7058fb6fcd2))
+
+
+### Documentation
+
+* **samples:** Add region tags ([#788](https://github.com/googleapis/python-bigtable/issues/788)) ([ecf539c](https://github.com/googleapis/python-bigtable/commit/ecf539c4c976fd9e5505b8abf0b697b218f09fef))
+
+## [2.18.1](https://github.com/googleapis/python-bigtable/compare/v2.18.0...v2.18.1) (2023-05-11)
+
+
+### Bug Fixes
+
+* Revert "Feat: Threaded MutationsBatcher" ([#773](https://github.com/googleapis/python-bigtable/issues/773)) ([a767cff](https://github.com/googleapis/python-bigtable/commit/a767cff95d990994f85f5fd05cc10f952087b49d))
+
+## [2.18.0](https://github.com/googleapis/python-bigtable/compare/v2.17.0...v2.18.0) (2023-05-10)
+
+
+### Features
+
+* Publish RateLimitInfo and FeatureFlag protos ([#768](https://github.com/googleapis/python-bigtable/issues/768)) ([171fea6](https://github.com/googleapis/python-bigtable/commit/171fea6de57a47f92a2a56050f8bfe7518144df7))
+* Threaded MutationsBatcher ([#722](https://github.com/googleapis/python-bigtable/issues/722)) ([7521a61](https://github.com/googleapis/python-bigtable/commit/7521a617c121ead96a21ca47959a53b2db2da090))
+
+
+### Bug Fixes
+
+* Pass the "retry" when calling read_rows. ([#759](https://github.com/googleapis/python-bigtable/issues/759)) ([505273b](https://github.com/googleapis/python-bigtable/commit/505273b72bf83d8f92d0e0a92d62f22bce96cc3d))
+
+
+### Documentation
+
+* Fix delete from column family example ([#764](https://github.com/googleapis/python-bigtable/issues/764)) ([128b4e1](https://github.com/googleapis/python-bigtable/commit/128b4e1f3eea2dad903d84c8f2933b17a5f0d226))
+* Fix formatting of request arg in docstring ([#756](https://github.com/googleapis/python-bigtable/issues/756)) ([45d3e43](https://github.com/googleapis/python-bigtable/commit/45d3e4308c4f494228c2e6e18a36285c557cb0c3))
+
+## [2.17.0](https://github.com/googleapis/python-bigtable/compare/v2.16.0...v2.17.0) (2023-03-01)
+
+
+### Features
+
+* Add new_partitions field for CloseStream for Cloud Bigtable ChangeStream ([#740](https://github.com/googleapis/python-bigtable/issues/740)) ([1adcad4](https://github.com/googleapis/python-bigtable/commit/1adcad440368f6d7df6710a013e7fab076461aed))
+
+## [2.16.0](https://github.com/googleapis/python-bigtable/compare/v2.15.0...v2.16.0) (2023-02-27)
+
+
+### Features
+
+* Enable "rest" transport in Python for services supporting numeric enums ([c5116e0](https://github.com/googleapis/python-bigtable/commit/c5116e097aacf9ddae249de57fab1849aff10d86))
+* Publish the Cloud Bigtable Change Streams ([c5116e0](https://github.com/googleapis/python-bigtable/commit/c5116e097aacf9ddae249de57fab1849aff10d86))
+
+
+### Bug Fixes
+
+* Add context manager return types ([beb5bf3](https://github.com/googleapis/python-bigtable/commit/beb5bf3bca4b517d095de3faa17d20e4d89fb295))
+* **deps:** Require google-api-core>=1.34.0,>=2.11.0 ([c5116e0](https://github.com/googleapis/python-bigtable/commit/c5116e097aacf9ddae249de57fab1849aff10d86))
+
+
+### Documentation
+
+* Add documentation for enums ([beb5bf3](https://github.com/googleapis/python-bigtable/commit/beb5bf3bca4b517d095de3faa17d20e4d89fb295))
+
+## [2.15.0](https://github.com/googleapis/python-bigtable/compare/v2.14.1...v2.15.0) (2023-01-10)
+
+
+### Features
+
+* Add support for python 3.11 ([#718](https://github.com/googleapis/python-bigtable/issues/718)) ([803a15e](https://github.com/googleapis/python-bigtable/commit/803a15ef0cd3713411eeb5d21258c12bbe1dcab6))
+
+## [2.14.1](https://github.com/googleapis/python-bigtable/compare/v2.14.0...v2.14.1) (2022-12-06)
+
+
+### Bug Fixes
+
+* **deps:** Require google-api-core >=1.34.0, >=2.11.0 ([e5875cb](https://github.com/googleapis/python-bigtable/commit/e5875cbe8551329fbb64f273ca21d6b7ada641ec))
+* Drop usage of pkg_resources ([e5875cb](https://github.com/googleapis/python-bigtable/commit/e5875cbe8551329fbb64f273ca21d6b7ada641ec))
+* Fix timeout default values ([e5875cb](https://github.com/googleapis/python-bigtable/commit/e5875cbe8551329fbb64f273ca21d6b7ada641ec))
+
+
+### Documentation
+
+* **samples:** Snippetgen should call await on the operation coroutine before calling result ([e5875cb](https://github.com/googleapis/python-bigtable/commit/e5875cbe8551329fbb64f273ca21d6b7ada641ec))
+
+## [2.14.0](https://github.com/googleapis/python-bigtable/compare/v2.13.2...v2.14.0) (2022-11-30)
+
+
+### Features
+
+* Add typing to proto.Message based class attributes ([c1538d5](https://github.com/googleapis/python-bigtable/commit/c1538d5c5a001a9febb4b466d3d09fd1fd167f66))
+* remove enum value ReadRowsRequest.RequestStatsView.REQUEST_STATS_EFFICIENCY ([c1538d5](https://github.com/googleapis/python-bigtable/commit/c1538d5c5a001a9febb4b466d3d09fd1fd167f66))
+* remove field ReadIterationStats.deletes_seen ([c1538d5](https://github.com/googleapis/python-bigtable/commit/c1538d5c5a001a9febb4b466d3d09fd1fd167f66))
+* remove field RequestStats.read_efficiency_stats ([c1538d5](https://github.com/googleapis/python-bigtable/commit/c1538d5c5a001a9febb4b466d3d09fd1fd167f66))
+* remove proto ReadEfficiencyStats ([c1538d5](https://github.com/googleapis/python-bigtable/commit/c1538d5c5a001a9febb4b466d3d09fd1fd167f66))
+* rename field RequestStats.all_read_stats to full_read_stats_view ([c1538d5](https://github.com/googleapis/python-bigtable/commit/c1538d5c5a001a9febb4b466d3d09fd1fd167f66))
+* rename proto AllReadStats to FullReadStatsView ([c1538d5](https://github.com/googleapis/python-bigtable/commit/c1538d5c5a001a9febb4b466d3d09fd1fd167f66))
+* rename proto ReadIteratorStats to ReadIterationStats ([c1538d5](https://github.com/googleapis/python-bigtable/commit/c1538d5c5a001a9febb4b466d3d09fd1fd167f66))
+
+
+### Bug Fixes
+
+* Add dict typing for client_options ([c1538d5](https://github.com/googleapis/python-bigtable/commit/c1538d5c5a001a9febb4b466d3d09fd1fd167f66))
+
+## [2.13.2](https://github.com/googleapis/python-bigtable/compare/v2.13.1...v2.13.2) (2022-10-20)
+
+
+### Bug Fixes
+
+* Respect deadlines for column family operations ([#687](https://github.com/googleapis/python-bigtable/issues/687)) ([df2e64a](https://github.com/googleapis/python-bigtable/commit/df2e64a79bbd8b28d0991706607af99d539320d1))
+
+## [2.13.1](https://github.com/googleapis/python-bigtable/compare/v2.13.0...v2.13.1) (2022-10-10)
+
+
+### Bug Fixes
+
+* **deps:** Allow protobuf 3.19.5 ([#682](https://github.com/googleapis/python-bigtable/issues/682)) ([0bb3420](https://github.com/googleapis/python-bigtable/commit/0bb3420decac74058ee099d72f8932556409f2aa))
+
+## [2.13.0](https://github.com/googleapis/python-bigtable/compare/v2.12.0...v2.13.0) (2022-09-29)
+
+
+### Features
+
+* Publish the RequestStats proto ([#676](https://github.com/googleapis/python-bigtable/issues/676)) ([199949b](https://github.com/googleapis/python-bigtable/commit/199949b2a930706654680b91a93f2a903bf112bf))
+
+
+### Bug Fixes
+
+* **deps:** Require protobuf >= 3.20.2 ([#679](https://github.com/googleapis/python-bigtable/issues/679)) ([030ef38](https://github.com/googleapis/python-bigtable/commit/030ef3868c442a8a21c4b4d6217b99cab09a1be7))
+
+## [2.12.0](https://github.com/googleapis/python-bigtable/compare/v2.11.3...v2.12.0) (2022-09-19)
+
+
+### Features
+
+* Publish CBT deletion_protection field in Table, UpdateTableRequest, and UpdateTable API ([#670](https://github.com/googleapis/python-bigtable/issues/670)) ([c57289c](https://github.com/googleapis/python-bigtable/commit/c57289c03335380694580202d746ca4f679dce9b))
+
+
+### Documentation
+
+* Remove unnecessary comment ([#674](https://github.com/googleapis/python-bigtable/issues/674)) ([9c62655](https://github.com/googleapis/python-bigtable/commit/9c62655de7fecd93ee7a1bb95b208d94798727cd))
+
+## [2.11.3](https://github.com/googleapis/python-bigtable/compare/v2.11.2...v2.11.3) (2022-08-17)
+
+
+### Performance Improvements
+
+* optimize row merging ([#628](https://github.com/googleapis/python-bigtable/issues/628)) ([c71ec70](https://github.com/googleapis/python-bigtable/commit/c71ec70e55f6e236e46127870a9ed4717eee5da5))
+
+## [2.11.2](https://github.com/googleapis/python-bigtable/compare/v2.11.1...v2.11.2) (2022-08-11)
+
+
+### Bug Fixes
+
+* **deps:** allow protobuf < 5.0.0 ([#631](https://github.com/googleapis/python-bigtable/issues/631)) ([fd54fc6](https://github.com/googleapis/python-bigtable/commit/fd54fc63340a3e01fae1ccc4c648dd90900f8a94))
+* **deps:** require proto-plus >= 1.22.0 ([fd54fc6](https://github.com/googleapis/python-bigtable/commit/fd54fc63340a3e01fae1ccc4c648dd90900f8a94))
+
+## [2.11.1](https://github.com/googleapis/python-bigtable/compare/v2.11.0...v2.11.1) (2022-08-08)
+
+
+### Bug Fixes
+
+* Retry the RST Stream error in mutate rows and read rows([#624](https://github.com/googleapis/python-bigtable/issues/624)) ([d24574a](https://github.com/googleapis/python-bigtable/commit/d24574a722de61bdeffa6588bcb08f56e62ba3bd))
+
+## [2.11.0](https://github.com/googleapis/python-bigtable/compare/v2.10.1...v2.11.0) (2022-08-04)
+
+
+### Features
+
+* add audience parameter ([a7a7699](https://github.com/googleapis/python-bigtable/commit/a7a76998fad3c12215527e4ebb517a1526cc152e))
+* add satisfies_pzs output only field ([#614](https://github.com/googleapis/python-bigtable/issues/614)) ([7dc1469](https://github.com/googleapis/python-bigtable/commit/7dc1469fef2dc38f1509b35a37e9c97381ab7601))
+* Add storage_utilization_gib_per_node to Autoscaling target ([a7a7699](https://github.com/googleapis/python-bigtable/commit/a7a76998fad3c12215527e4ebb517a1526cc152e))
+* Cloud Bigtable Undelete Table service and message proto files ([a7a7699](https://github.com/googleapis/python-bigtable/commit/a7a76998fad3c12215527e4ebb517a1526cc152e))
+
+
+### Bug Fixes
+
+* **deps:** require google-api-core>=1.32.0,>=2.8.0 ([a7a7699](https://github.com/googleapis/python-bigtable/commit/a7a76998fad3c12215527e4ebb517a1526cc152e))
+* require python 3.7+ ([#610](https://github.com/googleapis/python-bigtable/issues/610)) ([10d00f5](https://github.com/googleapis/python-bigtable/commit/10d00f5af5d5878c26529f5e48a5fb8d8385696d))
+
+
+### Performance Improvements
+
+* improve row merging ([#619](https://github.com/googleapis/python-bigtable/issues/619)) ([b4853e5](https://github.com/googleapis/python-bigtable/commit/b4853e59d0efd8a7b37f3fcb06b14dbd9f5d20a4))
+
## [2.10.1](https://github.com/googleapis/python-bigtable/compare/v2.10.0...v2.10.1) (2022-06-03)
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index 1579f6f6b..07ac8f218 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -22,7 +22,7 @@ In order to add a feature:
documentation.
- The feature must work fully on the following CPython versions:
- 3.7, 3.8, 3.9 and 3.10 on both UNIX and Windows.
+ 3.7, 3.8, 3.9, 3.10, 3.11, 3.12, 3.13 and 3.14 on both UNIX and Windows.
- The feature must not add unnecessary dependencies (where
"unnecessary" is of course subjective, but new dependencies should
@@ -72,7 +72,7 @@ We use `nox `__ to instrument our tests.
- To run a single unit test::
- $ nox -s unit-3.10 -- -k
+ $ nox -s unit-3.14 -- -k
.. note::
@@ -143,12 +143,12 @@ Running System Tests
$ nox -s system
# Run a single system test
- $ nox -s system-3.8 -- -k
+ $ nox -s system-3.9 -- -k
.. note::
- System tests are only configured to run under Python 3.8.
+ System tests are only configured to run under Python 3.9.
For expediency, we do not run them in older versions of Python 3.
This alone will not run the tests. You'll need to change some local
@@ -225,11 +225,19 @@ We support:
- `Python 3.8`_
- `Python 3.9`_
- `Python 3.10`_
+- `Python 3.11`_
+- `Python 3.12`_
+- `Python 3.13`_
+- `Python 3.14`_
.. _Python 3.7: https://docs.python.org/3.7/
.. _Python 3.8: https://docs.python.org/3.8/
.. _Python 3.9: https://docs.python.org/3.9/
.. _Python 3.10: https://docs.python.org/3.10/
+.. _Python 3.11: https://docs.python.org/3.11/
+.. _Python 3.12: https://docs.python.org/3.12/
+.. _Python 3.13: https://docs.python.org/3.13/
+.. _Python 3.14: https://docs.python.org/3.14/
Supported versions can be found in our ``noxfile.py`` `config`_.
diff --git a/MANIFEST.in b/MANIFEST.in
index e783f4c62..d6814cd60 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
-# Copyright 2020 Google LLC
+# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/README.rst b/README.rst
index 5f7d5809d..823b52c88 100644
--- a/README.rst
+++ b/README.rst
@@ -1,3 +1,7 @@
+:**NOTE**: **This github repository is archived. The repository contents and history have moved to** `google-cloud-python`_.
+
+.. _google-cloud-python: https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-bigtable
+
Python Client for Google Cloud Bigtable
=======================================
@@ -20,6 +24,30 @@ Analytics, Maps, and Gmail.
.. _Client Library Documentation: https://googleapis.dev/python/bigtable/latest
.. _Product Documentation: https://cloud.google.com/bigtable/docs
+
+Async Data Client
+-------------------------
+
+:code:`v2.23.0` includes a release of the new :code:`BigtableDataClientAsync` client, accessible at the import path
+:code:`google.cloud.bigtable.data`.
+
+The new client brings a simplified API and increased performance using asyncio.
+The new client is focused on the data API (i.e. reading and writing Bigtable data), with admin operations
+remaining exclusively in the existing synchronous client.
+
+Feedback and bug reports are welcome at cbt-python-client-v3-feedback@google.com,
+or through the Github `issue tracker`_.
+
+
+ .. note::
+
+ It is generally not recommended to use the async client in an otherwise synchronous codebase. To make use of asyncio's
+ performance benefits, the codebase should be designed to be async from the ground up.
+
+
+.. _issue tracker: https://github.com/googleapis/python-bigtable/issues
+
+
Quick Start
-----------
@@ -94,14 +122,3 @@ Next Steps
to see other available methods on the client.
- Read the `Product documentation`_ to learn
more about the product and see How-to Guides.
-
-``google-cloud-happybase``
---------------------------
-
-In addition to the core ``google-cloud-bigtable``, we provide a
-`google-cloud-happybase
-`__ library
-with the same interface as the popular `HappyBase
-`__ library. Unlike HappyBase,
-``google-cloud-happybase`` uses ``google-cloud-bigtable`` under the covers,
-rather than Apache HBase.
diff --git a/docs/admin_client/admin_client_usage.rst b/docs/admin_client/admin_client_usage.rst
new file mode 100644
index 000000000..8c6f4a5dc
--- /dev/null
+++ b/docs/admin_client/admin_client_usage.rst
@@ -0,0 +1,11 @@
+Admin Client
+============
+.. toctree::
+ :maxdepth: 2
+
+ services_
+ types_
+
+..
+ This should be the only handwritten RST file in this directory.
+ Everything else should be autogenerated.
diff --git a/docs/admin_client/bigtable_instance_admin.rst b/docs/admin_client/bigtable_instance_admin.rst
new file mode 100644
index 000000000..42f7caad7
--- /dev/null
+++ b/docs/admin_client/bigtable_instance_admin.rst
@@ -0,0 +1,10 @@
+BigtableInstanceAdmin
+---------------------------------------
+
+.. automodule:: google.cloud.bigtable_admin_v2.services.bigtable_instance_admin
+ :members:
+ :inherited-members:
+
+.. automodule:: google.cloud.bigtable_admin_v2.services.bigtable_instance_admin.pagers
+ :members:
+ :inherited-members:
diff --git a/docs/admin_client/bigtable_table_admin.rst b/docs/admin_client/bigtable_table_admin.rst
new file mode 100644
index 000000000..0fa4b276a
--- /dev/null
+++ b/docs/admin_client/bigtable_table_admin.rst
@@ -0,0 +1,10 @@
+BigtableTableAdmin
+------------------------------------
+
+.. automodule:: google.cloud.bigtable_admin_v2.overlay.services.bigtable_table_admin
+ :members:
+ :inherited-members:
+
+.. automodule:: google.cloud.bigtable_admin_v2.services.bigtable_table_admin.pagers
+ :members:
+ :inherited-members:
diff --git a/docs/admin_client/services_.rst b/docs/admin_client/services_.rst
new file mode 100644
index 000000000..ea55c7da1
--- /dev/null
+++ b/docs/admin_client/services_.rst
@@ -0,0 +1,7 @@
+Services for Google Cloud Bigtable Admin v2 API
+===============================================
+.. toctree::
+ :maxdepth: 2
+
+ bigtable_instance_admin
+ bigtable_table_admin
diff --git a/docs/admin_client/types_.rst b/docs/admin_client/types_.rst
new file mode 100644
index 000000000..ef32b9684
--- /dev/null
+++ b/docs/admin_client/types_.rst
@@ -0,0 +1,10 @@
+Types for Google Cloud Bigtable Admin v2 API
+============================================
+
+.. automodule:: google.cloud.bigtable_admin_v2.types
+ :members:
+ :show-inheritance:
+
+.. automodule:: google.cloud.bigtable_admin_v2.overlay.types
+ :members:
+ :show-inheritance:
diff --git a/docs/app-profile.rst b/docs/classic_client/app-profile.rst
similarity index 100%
rename from docs/app-profile.rst
rename to docs/classic_client/app-profile.rst
diff --git a/docs/backup.rst b/docs/classic_client/backup.rst
similarity index 100%
rename from docs/backup.rst
rename to docs/classic_client/backup.rst
diff --git a/docs/classic_client/batcher.rst b/docs/classic_client/batcher.rst
new file mode 100644
index 000000000..9ac335be1
--- /dev/null
+++ b/docs/classic_client/batcher.rst
@@ -0,0 +1,6 @@
+Mutations Batching
+~~~~~~~~~~~~~~~~~~
+
+.. automodule:: google.cloud.bigtable.batcher
+ :members:
+ :show-inheritance:
diff --git a/docs/client-intro.rst b/docs/classic_client/client-intro.rst
similarity index 100%
rename from docs/client-intro.rst
rename to docs/classic_client/client-intro.rst
diff --git a/docs/client.rst b/docs/classic_client/client.rst
similarity index 100%
rename from docs/client.rst
rename to docs/classic_client/client.rst
diff --git a/docs/cluster.rst b/docs/classic_client/cluster.rst
similarity index 100%
rename from docs/cluster.rst
rename to docs/classic_client/cluster.rst
diff --git a/docs/column-family.rst b/docs/classic_client/column-family.rst
similarity index 100%
rename from docs/column-family.rst
rename to docs/classic_client/column-family.rst
diff --git a/docs/data-api.rst b/docs/classic_client/data-api.rst
similarity index 97%
rename from docs/data-api.rst
rename to docs/classic_client/data-api.rst
index 01a49178f..9b50e9ec9 100644
--- a/docs/data-api.rst
+++ b/docs/classic_client/data-api.rst
@@ -1,6 +1,13 @@
Data API
========
+.. note::
+ This page describes how to use the Data API with the synchronous Bigtable client.
+ Examples for using the Data API with the async client can be found in the
+ `Getting Started Guide`_.
+
+.. _Getting Started Guide: https://cloud.google.com/bigtable/docs/samples-python-hello
+
After creating a :class:`Table ` and some
column families, you are ready to store and retrieve data.
diff --git a/docs/encryption-info.rst b/docs/classic_client/encryption-info.rst
similarity index 100%
rename from docs/encryption-info.rst
rename to docs/classic_client/encryption-info.rst
diff --git a/docs/instance-api.rst b/docs/classic_client/instance-api.rst
similarity index 100%
rename from docs/instance-api.rst
rename to docs/classic_client/instance-api.rst
diff --git a/docs/instance.rst b/docs/classic_client/instance.rst
similarity index 100%
rename from docs/instance.rst
rename to docs/classic_client/instance.rst
diff --git a/docs/row-data.rst b/docs/classic_client/row-data.rst
similarity index 100%
rename from docs/row-data.rst
rename to docs/classic_client/row-data.rst
diff --git a/docs/row-filters.rst b/docs/classic_client/row-filters.rst
similarity index 100%
rename from docs/row-filters.rst
rename to docs/classic_client/row-filters.rst
diff --git a/docs/row-set.rst b/docs/classic_client/row-set.rst
similarity index 100%
rename from docs/row-set.rst
rename to docs/classic_client/row-set.rst
diff --git a/docs/row.rst b/docs/classic_client/row.rst
similarity index 100%
rename from docs/row.rst
rename to docs/classic_client/row.rst
diff --git a/docs/snippets.py b/docs/classic_client/snippets.py
similarity index 99%
rename from docs/snippets.py
rename to docs/classic_client/snippets.py
index 1d93fdf12..c6059409d 100644
--- a/docs/snippets.py
+++ b/docs/classic_client/snippets.py
@@ -29,7 +29,7 @@
"""
-import datetime
+from datetime import datetime, timezone
import pytest
from google.api_core.exceptions import DeadlineExceeded
@@ -39,7 +39,7 @@
from test_utils.system import unique_resource_id
from test_utils.retry import RetryErrors
-from google.cloud._helpers import UTC
+
from google.cloud.bigtable import Client
from google.cloud.bigtable import enums
@@ -57,8 +57,8 @@
STORAGE_TYPE = enums.StorageType.SSD
LABEL_KEY = "python-snippet"
LABEL_STAMP = (
- datetime.datetime.utcnow()
- .replace(microsecond=0, tzinfo=UTC)
+ datetime.now(timezone.utc)
+ .replace(microsecond=0)
.strftime("%Y-%m-%dt%H-%M-%S")
)
LABELS = {LABEL_KEY: str(LABEL_STAMP)}
@@ -448,7 +448,6 @@ def test_bigtable_create_table():
def test_bigtable_list_tables():
-
# [START bigtable_api_list_tables]
from google.cloud.bigtable import Client
diff --git a/docs/snippets_table.py b/docs/classic_client/snippets_table.py
similarity index 99%
rename from docs/snippets_table.py
rename to docs/classic_client/snippets_table.py
index f27260425..1850e836b 100644
--- a/docs/snippets_table.py
+++ b/docs/classic_client/snippets_table.py
@@ -29,7 +29,7 @@
"""
-import datetime
+from datetime import datetime, timezone
import pytest
from google.api_core.exceptions import TooManyRequests
@@ -37,7 +37,6 @@
from test_utils.system import unique_resource_id
from test_utils.retry import RetryErrors
-from google.cloud._helpers import UTC
from google.cloud.bigtable import Client
from google.cloud.bigtable import enums
from google.cloud.bigtable import column_family
@@ -54,8 +53,8 @@
STORAGE_TYPE = enums.StorageType.SSD
LABEL_KEY = "python-snippet"
LABEL_STAMP = (
- datetime.datetime.utcnow()
- .replace(microsecond=0, tzinfo=UTC)
+ datetime.now(timezone.utc)
+ .replace(microsecond=0)
.strftime("%Y-%m-%dt%H-%M-%S")
)
LABELS = {LABEL_KEY: str(LABEL_STAMP)}
@@ -179,7 +178,7 @@ def test_bigtable_write_read_drop_truncate():
value = "value_{}".format(i).encode()
row = table.row(row_key)
row.set_cell(
- COLUMN_FAMILY_ID, col_name, value, timestamp=datetime.datetime.utcnow()
+ COLUMN_FAMILY_ID, col_name, value, timestamp=datetime.now(timezone.utc)
)
rows.append(row)
response = table.mutate_rows(rows)
@@ -270,7 +269,7 @@ def test_bigtable_mutations_batcher():
row_key = row_keys[0]
row = table.row(row_key)
row.set_cell(
- COLUMN_FAMILY_ID, column_name, "value-0", timestamp=datetime.datetime.utcnow()
+ COLUMN_FAMILY_ID, column_name, "value-0", timestamp=datetime.now(timezone.utc)
)
batcher.mutate(row)
# Add a collections of rows
@@ -279,7 +278,7 @@ def test_bigtable_mutations_batcher():
row = table.row(row_keys[i])
value = "value_{}".format(i).encode()
row.set_cell(
- COLUMN_FAMILY_ID, column_name, value, timestamp=datetime.datetime.utcnow()
+ COLUMN_FAMILY_ID, column_name, value, timestamp=datetime.now(timezone.utc)
)
rows.append(row)
batcher.mutate_rows(rows)
@@ -759,7 +758,7 @@ def test_bigtable_batcher_mutate_flush_mutate_rows():
row_key = b"row_key_1"
row = table.row(row_key)
row.set_cell(
- COLUMN_FAMILY_ID, COL_NAME1, "value-0", timestamp=datetime.datetime.utcnow()
+ COLUMN_FAMILY_ID, COL_NAME1, "value-0", timestamp=datetime.now(timezone.utc)
)
# In batcher, mutate will flush current batch if it
@@ -964,16 +963,15 @@ def test_bigtable_create_family_gc_nested():
def test_bigtable_row_data_cells_cell_value_cell_values():
-
value = b"value_in_col1"
row = Config.TABLE.row(b"row_key_1")
row.set_cell(
- COLUMN_FAMILY_ID, COL_NAME1, value, timestamp=datetime.datetime.utcnow()
+ COLUMN_FAMILY_ID, COL_NAME1, value, timestamp=datetime.now(timezone.utc)
)
row.commit()
row.set_cell(
- COLUMN_FAMILY_ID, COL_NAME1, value, timestamp=datetime.datetime.utcnow()
+ COLUMN_FAMILY_ID, COL_NAME1, value, timestamp=datetime.now(timezone.utc)
)
row.commit()
@@ -1051,7 +1049,7 @@ def test_bigtable_row_setcell_rowkey():
cell_val = b"cell-val"
row.set_cell(
- COLUMN_FAMILY_ID, COL_NAME1, cell_val, timestamp=datetime.datetime.utcnow()
+ COLUMN_FAMILY_ID, COL_NAME1, cell_val, timestamp=datetime.now(timezone.utc)
)
# [END bigtable_api_row_set_cell]
diff --git a/docs/table-api.rst b/docs/classic_client/table-api.rst
similarity index 100%
rename from docs/table-api.rst
rename to docs/classic_client/table-api.rst
diff --git a/docs/table.rst b/docs/classic_client/table.rst
similarity index 100%
rename from docs/table.rst
rename to docs/classic_client/table.rst
diff --git a/docs/usage.rst b/docs/classic_client/usage.rst
similarity index 90%
rename from docs/usage.rst
rename to docs/classic_client/usage.rst
index 33bf7bb7f..7a47f4d4a 100644
--- a/docs/usage.rst
+++ b/docs/classic_client/usage.rst
@@ -1,10 +1,15 @@
-Using the API
-=============
+Classic Client
+==============
.. toctree::
:maxdepth: 2
client-intro
+
+ instance-api
+ table-api
+ data-api
+
client
cluster
instance
@@ -17,6 +22,7 @@ Using the API
row-data
row-filters
row-set
+ batcher
In the hierarchy of API concepts
diff --git a/docs/conf.py b/docs/conf.py
index 34f3a4d08..d8f0352cd 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2021 Google LLC
+# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/docs/data_client/async_data_authorized_view.rst b/docs/data_client/async_data_authorized_view.rst
new file mode 100644
index 000000000..7d7312970
--- /dev/null
+++ b/docs/data_client/async_data_authorized_view.rst
@@ -0,0 +1,11 @@
+Authorized View Async
+~~~~~~~~~~~~~~~~~~~~~
+
+ .. note::
+
+ It is generally not recommended to use the async client in an otherwise synchronous codebase. To make use of asyncio's
+ performance benefits, the codebase should be designed to be async from the ground up.
+
+.. autoclass:: google.cloud.bigtable.data._async.client.AuthorizedViewAsync
+ :members:
+ :inherited-members:
diff --git a/docs/data_client/async_data_client.rst b/docs/data_client/async_data_client.rst
new file mode 100644
index 000000000..2ddcc090c
--- /dev/null
+++ b/docs/data_client/async_data_client.rst
@@ -0,0 +1,12 @@
+Bigtable Data Client Async
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ .. note::
+
+ It is generally not recommended to use the async client in an otherwise synchronous codebase. To make use of asyncio's
+ performance benefits, the codebase should be designed to be async from the ground up.
+
+
+.. autoclass:: google.cloud.bigtable.data.BigtableDataClientAsync
+ :members:
+ :show-inheritance:
diff --git a/docs/data_client/async_data_execute_query_iterator.rst b/docs/data_client/async_data_execute_query_iterator.rst
new file mode 100644
index 000000000..b911fab7f
--- /dev/null
+++ b/docs/data_client/async_data_execute_query_iterator.rst
@@ -0,0 +1,6 @@
+Execute Query Iterator Async
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. autoclass:: google.cloud.bigtable.data.execute_query.ExecuteQueryIteratorAsync
+ :members:
+ :show-inheritance:
diff --git a/docs/data_client/async_data_mutations_batcher.rst b/docs/data_client/async_data_mutations_batcher.rst
new file mode 100644
index 000000000..3e81f885a
--- /dev/null
+++ b/docs/data_client/async_data_mutations_batcher.rst
@@ -0,0 +1,6 @@
+Mutations Batcher Async
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. automodule:: google.cloud.bigtable.data._async.mutations_batcher
+ :members:
+ :show-inheritance:
diff --git a/docs/data_client/async_data_table.rst b/docs/data_client/async_data_table.rst
new file mode 100644
index 000000000..37c396570
--- /dev/null
+++ b/docs/data_client/async_data_table.rst
@@ -0,0 +1,11 @@
+Table Async
+~~~~~~~~~~~
+
+ .. note::
+
+ It is generally not recommended to use the async client in an otherwise synchronous codebase. To make use of asyncio's
+ performance benefits, the codebase should be designed to be async from the ground up.
+
+.. autoclass:: google.cloud.bigtable.data._async.client.TableAsync
+ :members:
+ :inherited-members:
diff --git a/docs/data_client/common_data_exceptions.rst b/docs/data_client/common_data_exceptions.rst
new file mode 100644
index 000000000..6180ef222
--- /dev/null
+++ b/docs/data_client/common_data_exceptions.rst
@@ -0,0 +1,6 @@
+Custom Exceptions
+~~~~~~~~~~~~~~~~~
+
+.. automodule:: google.cloud.bigtable.data.exceptions
+ :members:
+ :show-inheritance:
diff --git a/docs/data_client/common_data_execute_query_metadata.rst b/docs/data_client/common_data_execute_query_metadata.rst
new file mode 100644
index 000000000..69add630d
--- /dev/null
+++ b/docs/data_client/common_data_execute_query_metadata.rst
@@ -0,0 +1,6 @@
+Execute Query Metadata
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. automodule:: google.cloud.bigtable.data.execute_query.metadata
+ :members:
+ :show-inheritance:
diff --git a/docs/data_client/common_data_execute_query_values.rst b/docs/data_client/common_data_execute_query_values.rst
new file mode 100644
index 000000000..6c4fb71c1
--- /dev/null
+++ b/docs/data_client/common_data_execute_query_values.rst
@@ -0,0 +1,6 @@
+Execute Query Values
+~~~~~~~~~~~~~~~~~~~~
+
+.. automodule:: google.cloud.bigtable.data.execute_query.values
+ :members:
+ :show-inheritance:
diff --git a/docs/data_client/common_data_mutations.rst b/docs/data_client/common_data_mutations.rst
new file mode 100644
index 000000000..9d7a9eab2
--- /dev/null
+++ b/docs/data_client/common_data_mutations.rst
@@ -0,0 +1,6 @@
+Mutations
+~~~~~~~~~
+
+.. automodule:: google.cloud.bigtable.data.mutations
+ :members:
+ :show-inheritance:
diff --git a/docs/data_client/common_data_read_modify_write_rules.rst b/docs/data_client/common_data_read_modify_write_rules.rst
new file mode 100644
index 000000000..2f28ddf3f
--- /dev/null
+++ b/docs/data_client/common_data_read_modify_write_rules.rst
@@ -0,0 +1,6 @@
+Read Modify Write Rules
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. automodule:: google.cloud.bigtable.data.read_modify_write_rules
+ :members:
+ :show-inheritance:
diff --git a/docs/data_client/common_data_read_rows_query.rst b/docs/data_client/common_data_read_rows_query.rst
new file mode 100644
index 000000000..4e3e796d9
--- /dev/null
+++ b/docs/data_client/common_data_read_rows_query.rst
@@ -0,0 +1,6 @@
+Read Rows Query
+~~~~~~~~~~~~~~~
+
+.. automodule:: google.cloud.bigtable.data.read_rows_query
+ :members:
+ :show-inheritance:
diff --git a/docs/data_client/common_data_row.rst b/docs/data_client/common_data_row.rst
new file mode 100644
index 000000000..63bc71143
--- /dev/null
+++ b/docs/data_client/common_data_row.rst
@@ -0,0 +1,6 @@
+Rows and Cells
+~~~~~~~~~~~~~~
+
+.. automodule:: google.cloud.bigtable.data.row
+ :members:
+ :show-inheritance:
diff --git a/docs/data_client/common_data_row_filters.rst b/docs/data_client/common_data_row_filters.rst
new file mode 100644
index 000000000..22bda8a26
--- /dev/null
+++ b/docs/data_client/common_data_row_filters.rst
@@ -0,0 +1,62 @@
+Bigtable Row Filters
+====================
+
+It is possible to use a
+:class:`RowFilter `
+when constructing a :class:`ReadRowsQuery `
+
+The following basic filters
+are provided:
+
+* :class:`SinkFilter <.data.row_filters.SinkFilter>`
+* :class:`PassAllFilter <.data.row_filters.PassAllFilter>`
+* :class:`BlockAllFilter <.data.row_filters.BlockAllFilter>`
+* :class:`RowKeyRegexFilter <.data.row_filters.RowKeyRegexFilter>`
+* :class:`RowSampleFilter <.data.row_filters.RowSampleFilter>`
+* :class:`FamilyNameRegexFilter <.data.row_filters.FamilyNameRegexFilter>`
+* :class:`ColumnQualifierRegexFilter <.data.row_filters.ColumnQualifierRegexFilter>`
+* :class:`TimestampRangeFilter <.data.row_filters.TimestampRangeFilter>`
+* :class:`ColumnRangeFilter <.data.row_filters.ColumnRangeFilter>`
+* :class:`ValueRegexFilter <.data.row_filters.ValueRegexFilter>`
+* :class:`ValueRangeFilter <.data.row_filters.ValueRangeFilter>`
+* :class:`CellsRowOffsetFilter <.data.row_filters.CellsRowOffsetFilter>`
+* :class:`CellsRowLimitFilter <.data.row_filters.CellsRowLimitFilter>`
+* :class:`CellsColumnLimitFilter <.data.row_filters.CellsColumnLimitFilter>`
+* :class:`StripValueTransformerFilter <.data.row_filters.StripValueTransformerFilter>`
+* :class:`ApplyLabelFilter <.data.row_filters.ApplyLabelFilter>`
+
+In addition, these filters can be combined into composite filters with
+
+* :class:`RowFilterChain <.data.row_filters.RowFilterChain>`
+* :class:`RowFilterUnion <.data.row_filters.RowFilterUnion>`
+* :class:`ConditionalRowFilter <.data.row_filters.ConditionalRowFilter>`
+
+These rules can be nested arbitrarily, with a basic filter at the lowest
+level. For example:
+
+.. code:: python
+
+ # Filter in a specified column (matching any column family).
+ col1_filter = ColumnQualifierRegexFilter(b'columnbia')
+
+ # Create a filter to label results.
+ label1 = u'label-red'
+ label1_filter = ApplyLabelFilter(label1)
+
+ # Combine the filters to label all the cells in columnbia.
+ chain1 = RowFilterChain(filters=[col1_filter, label1_filter])
+
+ # Create a similar filter to label cells blue.
+ col2_filter = ColumnQualifierRegexFilter(b'columnseeya')
+ label2 = u'label-blue'
+ label2_filter = ApplyLabelFilter(label2)
+ chain2 = RowFilterChain(filters=[col2_filter, label2_filter])
+
+ # Bring our two labeled columns together.
+ row_filter = RowFilterUnion(filters=[chain1, chain2])
+
+----
+
+.. automodule:: google.cloud.bigtable.data.row_filters
+ :members:
+ :show-inheritance:
diff --git a/docs/data_client/data_client_usage.rst b/docs/data_client/data_client_usage.rst
new file mode 100644
index 000000000..708dafc62
--- /dev/null
+++ b/docs/data_client/data_client_usage.rst
@@ -0,0 +1,41 @@
+Data Client
+===========
+
+Sync Surface
+------------
+
+.. toctree::
+ :maxdepth: 3
+
+ sync_data_client
+ sync_data_table
+ sync_data_authorized_view
+ sync_data_mutations_batcher
+ sync_data_execute_query_iterator
+
+Async Surface
+-------------
+
+.. toctree::
+ :maxdepth: 3
+
+ async_data_client
+ async_data_table
+ async_data_authorized_view
+ async_data_mutations_batcher
+ async_data_execute_query_iterator
+
+Common Classes
+--------------
+
+.. toctree::
+ :maxdepth: 3
+
+ common_data_read_rows_query
+ common_data_row
+ common_data_row_filters
+ common_data_mutations
+ common_data_read_modify_write_rules
+ common_data_exceptions
+ common_data_execute_query_values
+ common_data_execute_query_metadata
diff --git a/docs/data_client/sync_data_authorized_view.rst b/docs/data_client/sync_data_authorized_view.rst
new file mode 100644
index 000000000..c0ac29721
--- /dev/null
+++ b/docs/data_client/sync_data_authorized_view.rst
@@ -0,0 +1,6 @@
+Authorized View
+~~~~~~~~~~~~~~~
+
+.. autoclass:: google.cloud.bigtable.data._sync_autogen.client.AuthorizedView
+ :members:
+ :inherited-members:
diff --git a/docs/data_client/sync_data_client.rst b/docs/data_client/sync_data_client.rst
new file mode 100644
index 000000000..cf7c00dad
--- /dev/null
+++ b/docs/data_client/sync_data_client.rst
@@ -0,0 +1,6 @@
+Bigtable Data Client
+~~~~~~~~~~~~~~~~~~~~
+
+.. autoclass:: google.cloud.bigtable.data.BigtableDataClient
+ :members:
+ :show-inheritance:
diff --git a/docs/data_client/sync_data_execute_query_iterator.rst b/docs/data_client/sync_data_execute_query_iterator.rst
new file mode 100644
index 000000000..6eb9f84db
--- /dev/null
+++ b/docs/data_client/sync_data_execute_query_iterator.rst
@@ -0,0 +1,6 @@
+Execute Query Iterator
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. autoclass:: google.cloud.bigtable.data.execute_query.ExecuteQueryIterator
+ :members:
+ :show-inheritance:
diff --git a/docs/data_client/sync_data_mutations_batcher.rst b/docs/data_client/sync_data_mutations_batcher.rst
new file mode 100644
index 000000000..2b7d1bfe0
--- /dev/null
+++ b/docs/data_client/sync_data_mutations_batcher.rst
@@ -0,0 +1,6 @@
+Mutations Batcher
+~~~~~~~~~~~~~~~~~
+
+.. automodule:: google.cloud.bigtable.data._sync_autogen.mutations_batcher
+ :members:
+ :show-inheritance:
diff --git a/docs/data_client/sync_data_table.rst b/docs/data_client/sync_data_table.rst
new file mode 100644
index 000000000..95c91eb27
--- /dev/null
+++ b/docs/data_client/sync_data_table.rst
@@ -0,0 +1,6 @@
+Table
+~~~~~
+
+.. autoclass:: google.cloud.bigtable.data.Table
+ :members:
+ :show-inheritance:
diff --git a/docs/index.rst b/docs/index.rst
index b1c8f0574..0694c8bb0 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -2,30 +2,26 @@
.. include:: multiprocessing.rst
-Using the API
+Client Types
-------------
.. toctree::
- :maxdepth: 2
-
- usage
-
-
-API Reference
--------------
-.. toctree::
- :maxdepth: 2
-
- instance-api
- table-api
- data-api
+ :maxdepth: 3
+ data_client/data_client_usage
+ classic_client/usage
+ admin_client/admin_client_usage
Changelog
---------
-For a list of all ``google-cloud-datastore`` releases:
+For a list of all ``google-cloud-bigtable`` releases:
.. toctree::
:maxdepth: 2
changelog
+
+.. toctree::
+ :hidden:
+
+ summary_overview.md
diff --git a/docs/scripts/patch_devsite_toc.py b/docs/scripts/patch_devsite_toc.py
new file mode 100644
index 000000000..fbb753daf
--- /dev/null
+++ b/docs/scripts/patch_devsite_toc.py
@@ -0,0 +1,277 @@
+# Copyright 2024 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
+#
+# https://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.
+"""
+This script will run after ``nox -s docfx`` is run. docfx is the api doc format used by
+google cloud. It is described here: https://github.com/googleapis/docuploader?tab=readme-ov-file#requirements-for-docfx-yaml-tarballs.
+
+One of the file used by docfx is toc.yml which is used to generate the table of contents sidebar.
+This script will patch file to create subfolders for each of the clients
+"""
+
+
+import glob
+import yaml
+import os
+import shutil
+
+# set working directory to /docs
+os.chdir(f"{os.path.dirname(os.path.abspath(__file__))}/{os.pardir}")
+
+
+def add_sections(toc_file_path, section_list, output_file_path=None):
+ """
+ Add new sections to the autogenerated docfx table of contents file
+
+ Takes in a list of TocSection objects, which should point to a directory of rst files
+ within the main /docs directory, which represents a self-contained section of content
+
+ :param toc_file_path: path to the autogenerated toc file
+ :param section_list: list of TocSection objects to add
+ :param output_file_path: path to save the updated toc file. If None, save to the input file
+ """
+ # remove any sections that are already in the toc
+ remove_sections(toc_file_path, [section.title for section in section_list])
+ # add new sections
+ current_toc = yaml.safe_load(open(toc_file_path, "r"))
+ for section in section_list:
+ print(f"Adding section {section.title}...")
+ current_toc[0]["items"].insert(-1, section.to_dict())
+ section.copy_markdown()
+ # save file
+ if output_file_path is None:
+ output_file_path = toc_file_path
+ with open(output_file_path, "w") as f:
+ yaml.dump(current_toc, f)
+
+
+def remove_sections(toc_file_path, section_list, output_file_path=None):
+ """
+ Remove sections from the autogenerated docfx table of contents file
+
+ Takes in a list of string section names to remove from the toc file
+
+ :param toc_file_path: path to the autogenerated toc file
+ :param section_list: list of section names to remove
+ :param output_file_path: path to save the updated toc file. If None, save to the input file
+ """
+ current_toc = yaml.safe_load(open(toc_file_path, "r"))
+ print(f"Removing sections {section_list}...")
+ new_items = [d for d in current_toc[0]["items"] if d["name"] not in section_list]
+ current_toc[0]["items"] = new_items
+ # save file
+ if output_file_path is None:
+ output_file_path = toc_file_path
+ with open(output_file_path, "w") as f:
+ yaml.dump(current_toc, f)
+
+
+class TocSection:
+ def __init__(self, dir_name, index_file_name):
+ """
+ :param dir_name: name of the directory containing the rst files
+ :param index_file_name: name of an index file within dir_name. This file
+ will not be included in the table of contents, but provides an ordered
+ list of the other files which should be included
+ """
+ self.dir_name = dir_name
+ self.index_file_name = index_file_name
+ index_file_path = os.path.join(dir_name, index_file_name)
+ # find set of files referenced by the index file
+ with open(index_file_path, "r") as f:
+ self.title = None
+ in_toc = False
+ self.items = []
+ for line in f:
+ # ignore empty lines
+ if not line.strip():
+ continue
+ # add files explictly included in the toc
+ if line.startswith(".. include::"):
+ file_base = os.path.splitext(line.split("::")[1].strip())[0]
+ self.items.append(
+ self.extract_toc_entry(
+ file_base, file_title=file_base.capitalize()
+ )
+ )
+ continue
+ if line.startswith(".. toctree::"):
+ in_toc = True
+ continue
+ # ignore directives
+ if ":" in line:
+ continue
+ # set tile as first line with no directive
+ if self.title is None:
+ self.title = line.strip()
+ if not in_toc:
+ continue
+ # bail when toc indented block is done
+ if not line.startswith(" ") and not line.startswith("\t"):
+ in_toc = False
+ continue
+ # extract entries
+ self.items.append(self.extract_toc_entry(line.strip()))
+
+ def extract_toc_entry(self, file_name, file_title=None):
+ """
+ Given the name of a file, extract the title and href for the toc entry,
+ and return as a dictionary
+ """
+ # load the file to get the title
+ with open(f"{self.dir_name}/{file_name}.rst", "r") as f2:
+ if file_title is None:
+ # use first line as title if not provided
+ file_title = f2.readline().strip()
+ return {"name": file_title, "href": f"{file_name}.md"}
+
+ def to_dict(self):
+ """
+ Convert the TocSection object to a dictionary that can be written to a yaml file
+ """
+ return {"name": self.title, "items": self.items}
+
+ def copy_markdown(self):
+ """
+ Copy markdown files from _build/markdown/dir_name to _build/html/docfx_yaml
+
+ This is necessary because the markdown files in sub-directories
+ are not copied over by the docfx build by default
+ """
+ for file in os.listdir("_build/markdown/" + self.dir_name):
+ shutil.copy(
+ f"_build/markdown/{self.dir_name}/{file}",
+ f"_build/html/docfx_yaml",
+ )
+
+ def validate_section(self, toc):
+ # Make sure each rst file is listed in the toc.
+ items_in_toc = [
+ d["items"] for d in toc[0]["items"] if d["name"] == self.title and ".rst"
+ ][0]
+ items_in_dir = [f for f in os.listdir(self.dir_name) if f.endswith(".rst")]
+ # subtract 1 for index
+ assert len(items_in_toc) == len(items_in_dir) - 1
+ for file in items_in_dir:
+ if file != self.index_file_name:
+ base_name, _ = os.path.splitext(file)
+ assert any(d["href"] == f"{base_name}.md" for d in items_in_toc)
+ # make sure the markdown files are present in the docfx_yaml directory
+ md_files = [d["href"] for d in items_in_toc]
+ for file in md_files:
+ assert os.path.exists(f"_build/html/docfx_yaml/{file}")
+
+
+class UIDFilteredTocSection(TocSection):
+ def __init__(self, toc_file_path, section_name, title, uid_prefix):
+ """Creates a filtered section denoted by section_name in the toc_file_path to items with the given UID prefix.
+
+ The section is then renamed to the title.
+ """
+ current_toc = yaml.safe_load(open(toc_file_path, "r"))
+ self.uid_prefix = uid_prefix
+
+ # Since we are looking for a specific section_name there should only
+ # be one match.
+ section_items = [
+ d for d in current_toc[0]["items"] if d["name"] == section_name
+ ][0]["items"]
+ filtered_items = [d for d in section_items if d["uid"].startswith(uid_prefix)]
+ self.items = filtered_items
+ self.title = title
+
+ def copy_markdown(self):
+ """
+ No-op because we are filtering on UIDs, not markdown files.
+ """
+ pass
+
+ def validate_section(self, toc):
+ uids_in_toc = set()
+
+ # A UID-filtered TOC tree looks like the following:
+ # - items:
+ # items:
+ # name:
+ # uid:
+ #
+ # Walk through the TOC tree to find all UIDs recursively.
+ def find_uids_in_items(items):
+ uids_in_toc.add(items["uid"])
+ for subitem in items.get("items", []):
+ find_uids_in_items(subitem)
+
+ items_in_toc = [d["items"] for d in toc[0]["items"] if d["name"] == self.title][
+ 0
+ ]
+ for item in items_in_toc:
+ find_uids_in_items(item)
+
+ # Now that we have all the UIDs, first match all of them
+ # with corresponding .yml files.
+ for uid in uids_in_toc:
+ assert os.path.exists(f"_build/html/docfx_yaml/{uid}.yml")
+
+ # Also validate that every uid yml file that starts with the uid_prefix
+ # exists in the section.
+ for filename in glob.glob(
+ f"{self.uid_prefix}*.yml", root_dir="_build/html/docfx_yaml"
+ ):
+ assert filename[:-4] in uids_in_toc
+
+
+def validate_toc(toc_file_path, expected_section_list, added_sections):
+ current_toc = yaml.safe_load(open(toc_file_path, "r"))
+ # make sure the set of sections matches what we expect
+ found_sections = [d["name"] for d in current_toc[0]["items"]]
+ assert (
+ found_sections == expected_section_list
+ ), f"Expected {expected_section_list}, found {found_sections}"
+ # make sure each customs ection is in the toc
+ for section in added_sections:
+ assert section.title in found_sections
+ section.validate_section(current_toc)
+ print("Toc validation passed")
+
+
+if __name__ == "__main__":
+ # Add secrtions for the async_data_client and classic_client directories
+ toc_path = "_build/html/docfx_yaml/toc.yml"
+
+ custom_sections = [
+ TocSection(dir_name="data_client", index_file_name="data_client_usage.rst"),
+ UIDFilteredTocSection(
+ toc_file_path=toc_path,
+ section_name="Bigtable Admin V2",
+ title="Admin Client",
+ uid_prefix="google.cloud.bigtable_admin_v2",
+ ),
+ TocSection(dir_name="classic_client", index_file_name="usage.rst"),
+ ]
+ add_sections(toc_path, custom_sections)
+ # Remove the Bigtable section, since it has duplicated data
+ remove_sections(toc_path, ["Bigtable", "Bigtable Admin V2"])
+ # run validation to make sure yaml is structured as we expect
+ validate_toc(
+ toc_file_path=toc_path,
+ expected_section_list=[
+ "Overview",
+ "bigtable APIs",
+ "Changelog",
+ "Multiprocessing",
+ "Data Client",
+ "Admin Client",
+ "Classic Client",
+ ],
+ added_sections=custom_sections,
+ )
diff --git a/docs/summary_overview.md b/docs/summary_overview.md
new file mode 100644
index 000000000..2379e8b6b
--- /dev/null
+++ b/docs/summary_overview.md
@@ -0,0 +1,22 @@
+[
+This is a templated file. Adding content to this file may result in it being
+reverted. Instead, if you want to place additional content, create an
+"overview_content.md" file in `docs/` directory. The Sphinx tool will
+pick up on the content and merge the content.
+]: #
+
+# Cloud Bigtable API
+
+Overview of the APIs available for Cloud Bigtable API.
+
+## All entries
+
+Classes, methods and properties & attributes for
+Cloud Bigtable API.
+
+[classes](https://cloud.google.com/python/docs/reference/bigtable/latest/summary_class.html)
+
+[methods](https://cloud.google.com/python/docs/reference/bigtable/latest/summary_method.html)
+
+[properties and
+attributes](https://cloud.google.com/python/docs/reference/bigtable/latest/summary_property.html)
diff --git a/google/__init__.py b/google/__init__.py
deleted file mode 100644
index a5ba80656..000000000
--- a/google/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-try:
- import pkg_resources
-
- pkg_resources.declare_namespace(__name__)
-except ImportError:
- pass
diff --git a/google/cloud/__init__.py b/google/cloud/__init__.py
deleted file mode 100644
index a5ba80656..000000000
--- a/google/cloud/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-try:
- import pkg_resources
-
- pkg_resources.declare_namespace(__name__)
-except ImportError:
- pass
diff --git a/google/cloud/bigtable/__init__.py b/google/cloud/bigtable/__init__.py
index a54096624..7331ff241 100644
--- a/google/cloud/bigtable/__init__.py
+++ b/google/cloud/bigtable/__init__.py
@@ -14,17 +14,12 @@
"""Google Cloud Bigtable API package."""
-
-from typing import Optional
-import pkg_resources
-
from google.cloud.bigtable.client import Client
-__version__: Optional[str]
-try:
- __version__ = pkg_resources.get_distribution("google-cloud-bigtable").version
-except pkg_resources.DistributionNotFound:
- __version__ = None
+from google.cloud.bigtable import gapic_version as package_version
+
+__version__: str
+__version__ = package_version.__version__
__all__ = ["__version__", "Client"]
diff --git a/google/cloud/bigtable/backup.py b/google/cloud/bigtable/backup.py
index 6986d730a..f6fa24421 100644
--- a/google/cloud/bigtable/backup.py
+++ b/google/cloud/bigtable/backup.py
@@ -17,7 +17,7 @@
import re
from google.cloud._helpers import _datetime_to_pb_timestamp # type: ignore
-from google.cloud.bigtable_admin_v2 import BigtableTableAdminClient
+from google.cloud.bigtable_admin_v2 import BaseBigtableTableAdminClient
from google.cloud.bigtable_admin_v2.types import table
from google.cloud.bigtable.encryption_info import EncryptionInfo
from google.cloud.bigtable.policy import Policy
@@ -28,7 +28,7 @@
r"^projects/(?P[^/]+)/"
r"instances/(?P[a-z][-a-z0-9]*)/"
r"clusters/(?P[a-z][-a-z0-9]*)/"
- r"backups/(?P[a-z][a-z0-9_\-]*[a-z0-9])$"
+ r"backups/(?P[_a-zA-Z0-9][-_.a-zA-Z0-9]*)$"
)
_TABLE_NAME_RE = re.compile(
@@ -106,7 +106,7 @@ def name(self):
if not self._cluster:
raise ValueError('"cluster" parameter must be set')
- return BigtableTableAdminClient.backup_path(
+ return BaseBigtableTableAdminClient.backup_path(
project=self._instance._client.project,
instance=self._instance.instance_id,
cluster=self._cluster,
@@ -141,7 +141,7 @@ def parent(self):
:returns: A full path to the parent cluster.
"""
if not self._parent and self._cluster:
- self._parent = BigtableTableAdminClient.cluster_path(
+ self._parent = BaseBigtableTableAdminClient.cluster_path(
project=self._instance._client.project,
instance=self._instance.instance_id,
cluster=self._cluster,
@@ -163,7 +163,7 @@ def source_table(self):
:returns: The Table name.
"""
if not self._source_table and self.table_id:
- self._source_table = BigtableTableAdminClient.table_path(
+ self._source_table = BaseBigtableTableAdminClient.table_path(
project=self._instance._client.project,
instance=self._instance.instance_id,
table=self.table_id,
@@ -226,7 +226,7 @@ def size_bytes(self):
def state(self):
"""The current state of this Backup.
- :rtype: :class:`~google.cloud.bigtable_admin_v2.gapic.enums.Backup.State`
+ :rtype: :class:`~google.cloud.bigtable_admin_v2.types.table.Backup.State`
:returns: The current state of this Backup.
"""
return self._state
@@ -305,8 +305,7 @@ def create(self, cluster_id=None):
created Backup.
:rtype: :class:`~google.api_core.operation.Operation`
- :returns: :class:`~google.cloud.bigtable_admin_v2.types._OperationFuture`
- instance, to be used to poll the status of the 'create' request
+ :returns: A future to be used to poll the status of the 'create' request
:raises Conflict: if the Backup already exists
:raises NotFound: if the Instance owning the Backup does not exist
:raises BadRequest: if the `table` or `expire_time` values are invalid,
@@ -412,7 +411,7 @@ def restore(self, table_id, instance_id=None):
:param instance_id: (Optional) The ID of the Instance to restore the
backup into, if different from the current one.
- :rtype: :class:`~google.cloud.bigtable_admin_v2.types._OperationFuture`
+ :rtype: :class:`~google.api_core.operation.Operation`
:returns: A future to be used to poll the status of the 'restore'
request.
@@ -426,14 +425,14 @@ def restore(self, table_id, instance_id=None):
"""
api = self._instance._client.table_admin_client
if instance_id:
- parent = BigtableTableAdminClient.instance_path(
+ parent = BaseBigtableTableAdminClient.instance_path(
project=self._instance._client.project,
instance=instance_id,
)
else:
parent = self._instance.name
- return api.restore_table(
+ return api._restore_table(
request={"parent": parent, "table_id": table_id, "backup": self.name}
)
diff --git a/google/cloud/bigtable/batcher.py b/google/cloud/bigtable/batcher.py
index 3c23f4436..f9b85386d 100644
--- a/google/cloud/bigtable/batcher.py
+++ b/google/cloud/bigtable/batcher.py
@@ -13,104 +13,265 @@
# limitations under the License.
"""User friendly container for Google Cloud Bigtable MutationBatcher."""
+import threading
+import queue
+import concurrent.futures
+import atexit
-FLUSH_COUNT = 1000
-MAX_MUTATIONS = 100000
-MAX_ROW_BYTES = 5242880 # 5MB
+from google.api_core.exceptions import from_grpc_status
+from dataclasses import dataclass
-class MaxMutationsError(ValueError):
- """The number of mutations for bulk request is too big."""
+FLUSH_COUNT = 100 # after this many elements, send out the batch
+
+MAX_MUTATION_SIZE = 20 * 1024 * 1024 # 20MB # after this many bytes, send out the batch
+
+MAX_OUTSTANDING_BYTES = 100 * 1024 * 1024 # 100MB # max inflight byte size.
+
+MAX_OUTSTANDING_ELEMENTS = 100000 # max inflight mutations.
+
+
+class MutationsBatchError(Exception):
+ """Error in the batch request"""
+
+ def __init__(self, message, exc):
+ self.exc = exc
+ self.message = message
+ super().__init__(self.message)
+
+
+class _MutationsBatchQueue(object):
+ """Private Threadsafe Queue to hold rows for batching."""
+
+ def __init__(self, max_mutation_bytes=MAX_MUTATION_SIZE, flush_count=FLUSH_COUNT):
+ """Specify the queue constraints"""
+ self._queue = queue.Queue()
+ self.total_mutation_count = 0
+ self.total_size = 0
+ self.max_mutation_bytes = max_mutation_bytes
+ self.flush_count = flush_count
+
+ def get(self):
+ """
+ Retrieve an item from the queue. Recalculate queue size.
+
+ If the queue is empty, return None.
+ """
+ try:
+ row = self._queue.get_nowait()
+ mutation_size = row.get_mutations_size()
+ self.total_mutation_count -= len(row._get_mutations())
+ self.total_size -= mutation_size
+ return row
+ except queue.Empty:
+ return None
+
+ def put(self, item):
+ """Insert an item to the queue. Recalculate queue size."""
+
+ mutation_count = len(item._get_mutations())
+
+ self._queue.put(item)
+
+ self.total_size += item.get_mutations_size()
+ self.total_mutation_count += mutation_count
+
+ def full(self):
+ """Check if the queue is full."""
+ if (
+ self.total_mutation_count >= self.flush_count
+ or self.total_size >= self.max_mutation_bytes
+ ):
+ return True
+ return False
+
+
+@dataclass
+class _BatchInfo:
+ """Keeping track of size of a batch"""
+
+ mutations_count: int = 0
+ rows_count: int = 0
+ mutations_size: int = 0
+
+
+class _FlowControl(object):
+ def __init__(
+ self,
+ max_mutations=MAX_OUTSTANDING_ELEMENTS,
+ max_mutation_bytes=MAX_OUTSTANDING_BYTES,
+ ):
+ """Control the inflight requests. Keep track of the mutations, row bytes and row counts.
+ As requests to backend are being made, adjust the number of mutations being processed.
+
+ If threshold is reached, block the flow.
+ Reopen the flow as requests are finished.
+ """
+ self.max_mutations = max_mutations
+ self.max_mutation_bytes = max_mutation_bytes
+ self.inflight_mutations = 0
+ self.inflight_size = 0
+ self.event = threading.Event()
+ self.event.set()
+ self._lock = threading.Lock()
+
+ def is_blocked(self):
+ """Returns True if:
+
+ - inflight mutations >= max_mutations, or
+ - inflight bytes size >= max_mutation_bytes, or
+ """
+
+ return (
+ self.inflight_mutations >= self.max_mutations
+ or self.inflight_size >= self.max_mutation_bytes
+ )
+
+ def control_flow(self, batch_info):
+ """
+ Calculate the resources used by this batch
+ """
+
+ with self._lock:
+ self.inflight_mutations += batch_info.mutations_count
+ self.inflight_size += batch_info.mutations_size
+ self.set_flow_control_status()
+
+ def wait(self):
+ """
+ Wait until flow control pushback has been released.
+ It awakens as soon as `event` is set.
+ """
+ self.event.wait()
+
+ def set_flow_control_status(self):
+ """Check the inflight mutations and size.
+
+ If values exceed the allowed threshold, block the event.
+ """
+ if self.is_blocked():
+ self.event.clear() # sleep
+ else:
+ self.event.set() # awaken the threads
+
+ def release(self, batch_info):
+ """
+ Release the resources.
+ Decrement the row size to allow enqueued mutations to be run.
+ """
+ with self._lock:
+ self.inflight_mutations -= batch_info.mutations_count
+ self.inflight_size -= batch_info.mutations_size
+ self.set_flow_control_status()
class MutationsBatcher(object):
"""A MutationsBatcher is used in batch cases where the number of mutations
- is large or unknown. It will store DirectRows in memory until one of the
- size limits is reached, or an explicit call to flush() is performed. When
- a flush event occurs, the DirectRows in memory will be sent to Cloud
+ is large or unknown. It will store :class:`DirectRow` in memory until one of the
+ size limits is reached, or an explicit call to :func:`flush()` is performed. When
+ a flush event occurs, the :class:`DirectRow` in memory will be sent to Cloud
Bigtable. Batching mutations is more efficient than sending individual
request.
This class is not suited for usage in systems where each mutation
must be guaranteed to be sent, since calling mutate may only result in an
- in-memory change. In a case of a system crash, any DirectRows remaining in
+ in-memory change. In a case of a system crash, any :class:`DirectRow` remaining in
memory will not necessarily be sent to the service, even after the
- completion of the mutate() method.
+ completion of the :func:`mutate()` method.
- TODO: Performance would dramatically improve if this class had the
- capability of asynchronous, parallel RPCs.
+ Note on thread safety: The same :class:`MutationBatcher` cannot be shared by multiple end-user threads.
:type table: class
:param table: class:`~google.cloud.bigtable.table.Table`.
:type flush_count: int
:param flush_count: (Optional) Max number of rows to flush. If it
- reaches the max number of rows it calls finish_batch() to mutate the
- current row batch. Default is FLUSH_COUNT (1000 rows).
+ reaches the max number of rows it calls finish_batch() to mutate the
+ current row batch. Default is FLUSH_COUNT (1000 rows).
:type max_row_bytes: int
:param max_row_bytes: (Optional) Max number of row mutations size to
- flush. If it reaches the max number of row mutations size it calls
- finish_batch() to mutate the current row batch. Default is MAX_ROW_BYTES
- (5 MB).
+ flush. If it reaches the max number of row mutations size it calls
+ finish_batch() to mutate the current row batch. Default is MAX_ROW_BYTES
+ (5 MB).
+
+ :type flush_interval: float
+ :param flush_interval: (Optional) The interval (in seconds) between asynchronous flush.
+ Default is 1 second.
+
+ :type batch_completed_callback: Callable[list:[`~google.rpc.status_pb2.Status`]] = None
+ :param batch_completed_callback: (Optional) A callable for handling responses
+ after the current batch is sent. The callable function expect a list of grpc
+ Status.
"""
- def __init__(self, table, flush_count=FLUSH_COUNT, max_row_bytes=MAX_ROW_BYTES):
- self.rows = []
- self.total_mutation_count = 0
- self.total_size = 0
+ def __init__(
+ self,
+ table,
+ flush_count=FLUSH_COUNT,
+ max_row_bytes=MAX_MUTATION_SIZE,
+ flush_interval=1,
+ batch_completed_callback=None,
+ ):
+ self._rows = _MutationsBatchQueue(
+ max_mutation_bytes=max_row_bytes, flush_count=flush_count
+ )
self.table = table
- self.flush_count = flush_count
- self.max_row_bytes = max_row_bytes
+ self._executor = concurrent.futures.ThreadPoolExecutor()
+ atexit.register(self.close)
+ self._timer = threading.Timer(flush_interval, self.flush)
+ self._timer.start()
+ self.flow_control = _FlowControl(
+ max_mutations=MAX_OUTSTANDING_ELEMENTS,
+ max_mutation_bytes=MAX_OUTSTANDING_BYTES,
+ )
+ self.futures_mapping = {}
+ self.exceptions = queue.Queue()
+ self._user_batch_completed_callback = batch_completed_callback
+
+ @property
+ def flush_count(self):
+ return self._rows.flush_count
+
+ @property
+ def max_row_bytes(self):
+ return self._rows.max_mutation_bytes
+
+ def __enter__(self):
+ """Starting the MutationsBatcher as a context manager"""
+ return self
def mutate(self, row):
"""Add a row to the batch. If the current batch meets one of the size
- limits, the batch is sent synchronously.
+ limits, the batch is sent asynchronously.
For example:
- .. literalinclude:: snippets.py
+ .. literalinclude:: snippets_table.py
:start-after: [START bigtable_api_batcher_mutate]
:end-before: [END bigtable_api_batcher_mutate]
:dedent: 4
:type row: class
- :param row: class:`~google.cloud.bigtable.row.DirectRow`.
+ :param row: :class:`~google.cloud.bigtable.row.DirectRow`.
:raises: One of the following:
- * :exc:`~.table._BigtableRetryableError` if any
- row returned a transient error.
- * :exc:`RuntimeError` if the number of responses doesn't
- match the number of rows that were retried
- * :exc:`.batcher.MaxMutationsError` if any row exceeds max
- mutations count.
- """
- mutation_count = len(row._get_mutations())
- if mutation_count > MAX_MUTATIONS:
- raise MaxMutationsError(
- "The row key {} exceeds the number of mutations {}.".format(
- row.row_key, mutation_count
- )
- )
-
- if (self.total_mutation_count + mutation_count) >= MAX_MUTATIONS:
- self.flush()
-
- self.rows.append(row)
- self.total_mutation_count += mutation_count
- self.total_size += row.get_mutations_size()
+ * :exc:`~.table._BigtableRetryableError` if any row returned a transient error.
+ * :exc:`RuntimeError` if the number of responses doesn't match the number of rows that were retried
+ """
+ self._rows.put(row)
- if self.total_size >= self.max_row_bytes or len(self.rows) >= self.flush_count:
- self.flush()
+ if self._rows.full():
+ self._flush_async()
def mutate_rows(self, rows):
"""Add multiple rows to the batch. If the current batch meets one of the size
- limits, the batch is sent synchronously.
+ limits, the batch is sent asynchronously.
For example:
- .. literalinclude:: snippets.py
+ .. literalinclude:: snippets_table.py
:start-after: [START bigtable_api_batcher_mutate_rows]
:end-before: [END bigtable_api_batcher_mutate_rows]
:dedent: 4
@@ -119,28 +280,135 @@ def mutate_rows(self, rows):
:param rows: list:[`~google.cloud.bigtable.row.DirectRow`].
:raises: One of the following:
- * :exc:`~.table._BigtableRetryableError` if any
- row returned a transient error.
- * :exc:`RuntimeError` if the number of responses doesn't
- match the number of rows that were retried
- * :exc:`.batcher.MaxMutationsError` if any row exceeds max
- mutations count.
+ * :exc:`~.table._BigtableRetryableError` if any row returned a transient error.
+ * :exc:`RuntimeError` if the number of responses doesn't match the number of rows that were retried
"""
for row in rows:
self.mutate(row)
def flush(self):
- """Sends the current. batch to Cloud Bigtable.
+ """Sends the current batch to Cloud Bigtable synchronously.
For example:
- .. literalinclude:: snippets.py
+ .. literalinclude:: snippets_table.py
:start-after: [START bigtable_api_batcher_flush]
:end-before: [END bigtable_api_batcher_flush]
:dedent: 4
+ :raises:
+ * :exc:`.batcherMutationsBatchError` if there's any error in the mutations.
+ """
+ rows_to_flush = []
+ row = self._rows.get()
+ while row is not None:
+ rows_to_flush.append(row)
+ row = self._rows.get()
+ response = self._flush_rows(rows_to_flush)
+ return response
+
+ def _flush_async(self):
+ """Sends the current batch to Cloud Bigtable asynchronously.
+
+ :raises:
+ * :exc:`.batcherMutationsBatchError` if there's any error in the mutations.
+ """
+ next_row = self._rows.get()
+ while next_row is not None:
+ # start a new batch
+ rows_to_flush = [next_row]
+ batch_info = _BatchInfo(
+ mutations_count=len(next_row._get_mutations()),
+ rows_count=1,
+ mutations_size=next_row.get_mutations_size(),
+ )
+ # fill up batch with rows
+ next_row = self._rows.get()
+ while next_row is not None and self._row_fits_in_batch(
+ next_row, batch_info
+ ):
+ rows_to_flush.append(next_row)
+ batch_info.mutations_count += len(next_row._get_mutations())
+ batch_info.rows_count += 1
+ batch_info.mutations_size += next_row.get_mutations_size()
+ next_row = self._rows.get()
+ # send batch over network
+ # wait for resources to become available
+ self.flow_control.wait()
+ # once unblocked, submit the batch
+ # event flag will be set by control_flow to block subsequent thread, but not blocking this one
+ self.flow_control.control_flow(batch_info)
+ future = self._executor.submit(self._flush_rows, rows_to_flush)
+ # schedule release of resources from flow control
+ self.futures_mapping[future] = batch_info
+ future.add_done_callback(self._batch_completed_callback)
+
+ def _batch_completed_callback(self, future):
+ """Callback for when the mutation has finished to clean up the current batch
+ and release items from the flow controller.
+ Raise exceptions if there's any.
+ Release the resources locked by the flow control and allow enqueued tasks to be run.
+ """
+ processed_rows = self.futures_mapping[future]
+ self.flow_control.release(processed_rows)
+ del self.futures_mapping[future]
+
+ def _row_fits_in_batch(self, row, batch_info):
+ """Checks if a row can fit in the current batch.
+
+ :type row: class
+ :param row: :class:`~google.cloud.bigtable.row.DirectRow`.
+
+ :type batch_info: :class:`_BatchInfo`
+ :param batch_info: Information about the current batch.
+
+ :rtype: bool
+ :returns: True if the row can fit in the current batch.
+ """
+ new_rows_count = batch_info.rows_count + 1
+ new_mutations_count = batch_info.mutations_count + len(row._get_mutations())
+ new_mutations_size = batch_info.mutations_size + row.get_mutations_size()
+ return (
+ new_rows_count <= self.flush_count
+ and new_mutations_size <= self.max_row_bytes
+ and new_mutations_count <= self.flow_control.max_mutations
+ and new_mutations_size <= self.flow_control.max_mutation_bytes
+ )
+
+ def _flush_rows(self, rows_to_flush):
+ """Mutate the specified rows.
+
+ :raises:
+ * :exc:`.batcherMutationsBatchError` if there's any error in the mutations.
+ """
+ responses = []
+ if len(rows_to_flush) > 0:
+ response = self.table.mutate_rows(rows_to_flush)
+
+ if self._user_batch_completed_callback:
+ self._user_batch_completed_callback(response)
+
+ for result in response:
+ if result.code != 0:
+ exc = from_grpc_status(result.code, result.message)
+ self.exceptions.put(exc)
+ responses.append(result)
+
+ return responses
+
+ def __exit__(self, exc_type, exc_value, exc_traceback):
+ """Clean up resources. Flush and shutdown the ThreadPoolExecutor."""
+ self.close()
+
+ def close(self):
+ """Clean up resources. Flush and shutdown the ThreadPoolExecutor.
+ Any errors will be raised.
+
+ :raises:
+ * :exc:`.batcherMutationsBatchError` if there's any error in the mutations.
"""
- if len(self.rows) != 0:
- self.table.mutate_rows(self.rows)
- self.total_mutation_count = 0
- self.total_size = 0
- self.rows = []
+ self.flush()
+ self._executor.shutdown(wait=True)
+ atexit.unregister(self.close)
+ if self.exceptions.qsize() > 0:
+ exc = list(self.exceptions.queue)
+ raise MutationsBatchError("Errors in batch mutations.", exc=exc)
diff --git a/google/cloud/bigtable/client.py b/google/cloud/bigtable/client.py
index c82a268c6..37de10b6e 100644
--- a/google/cloud/bigtable/client.py
+++ b/google/cloud/bigtable/client.py
@@ -32,7 +32,6 @@
import grpc # type: ignore
from google.api_core.gapic_v1 import client_info as client_info_lib
-import google.auth # type: ignore
from google.auth.credentials import AnonymousCredentials # type: ignore
from google.cloud import bigtable_v2
@@ -215,58 +214,21 @@ def _get_scopes(self):
return scopes
def _emulator_channel(self, transport, options):
- """Create a channel using self._credentials
+ """Create a channel for use with the Bigtable emulator.
- Works in a similar way to ``grpc.secure_channel`` but using
- ``grpc.local_channel_credentials`` rather than
- ``grpc.ssh_channel_credentials`` to allow easy connection to a
- local emulator.
+ Insecure channels are used for the emulator as secure channels
+ cannot be used to communicate on some environments.
+ https://github.com/googleapis/python-firestore/issues/359
Returns:
grpc.Channel or grpc.aio.Channel
"""
- # TODO: Implement a special credentials type for emulator and use
- # "transport.create_channel" to create gRPC channels once google-auth
- # extends it's allowed credentials types.
# Note: this code also exists in the firestore client.
if "GrpcAsyncIOTransport" in str(transport.__name__):
- return grpc.aio.secure_channel(
- self._emulator_host,
- self._local_composite_credentials(),
- options=options,
- )
+ channel_fn = grpc.aio.insecure_channel
else:
- return grpc.secure_channel(
- self._emulator_host,
- self._local_composite_credentials(),
- options=options,
- )
-
- def _local_composite_credentials(self):
- """Create credentials for the local emulator channel.
-
- :return: grpc.ChannelCredentials
- """
- credentials = google.auth.credentials.with_scopes_if_required(
- self._credentials, None
- )
- request = google.auth.transport.requests.Request()
-
- # Create the metadata plugin for inserting the authorization header.
- metadata_plugin = google.auth.transport.grpc.AuthMetadataPlugin(
- credentials, request
- )
-
- # Create a set of grpc.CallCredentials using the metadata plugin.
- google_auth_credentials = grpc.metadata_call_credentials(metadata_plugin)
-
- # Using the local_credentials to allow connection to emulator
- local_credentials = grpc.local_channel_credentials()
-
- # Combine the local credentials and the authorization credentials.
- return grpc.composite_channel_credentials(
- local_credentials, google_auth_credentials
- )
+ channel_fn = grpc.insecure_channel
+ return channel_fn(self._emulator_host, options=options)
def _create_gapic_client_channel(self, client_class, grpc_transport):
if self._emulator_host is not None:
@@ -363,11 +325,11 @@ def table_admin_client(self):
raise ValueError("Client is not an admin client.")
transport = self._create_gapic_client_channel(
- bigtable_admin_v2.BigtableTableAdminClient,
+ bigtable_admin_v2.BaseBigtableTableAdminClient,
BigtableTableAdminGrpcTransport,
)
klass = _create_gapic_client(
- bigtable_admin_v2.BigtableTableAdminClient,
+ bigtable_admin_v2.BaseBigtableTableAdminClient,
client_options=self._admin_client_options,
transport=transport,
)
diff --git a/google/cloud/bigtable/cluster.py b/google/cloud/bigtable/cluster.py
index 11fb5492d..967ec707e 100644
--- a/google/cloud/bigtable/cluster.py
+++ b/google/cloud/bigtable/cluster.py
@@ -511,9 +511,11 @@ def delete(self):
def _to_pb(self):
"""Create cluster proto buff message for API calls"""
client = self._instance._client
- location = client.instance_admin_client.common_location_path(
- client.project, self.location_id
- )
+ location = None
+ if self.location_id:
+ location = client.instance_admin_client.common_location_path(
+ client.project, self.location_id
+ )
cluster_pb = instance.Cluster(
location=location,
diff --git a/google/cloud/bigtable/column_family.py b/google/cloud/bigtable/column_family.py
index 466011923..80232958d 100644
--- a/google/cloud/bigtable/column_family.py
+++ b/google/cloud/bigtable/column_family.py
@@ -20,6 +20,7 @@
from google.cloud.bigtable_admin_v2.types import (
bigtable_table_admin as table_admin_v2_pb2,
)
+from google.api_core.gapic_v1.method import DEFAULT
class GarbageCollectionRule(object):
@@ -275,7 +276,8 @@ def create(self):
# data it contains are the GC rule and the column family ID already
# stored on this instance.
client.table_admin_client.modify_column_families(
- request={"name": self._table.name, "modifications": [modification]}
+ request={"name": self._table.name, "modifications": [modification]},
+ timeout=DEFAULT,
)
def update(self):
@@ -302,7 +304,8 @@ def update(self):
# data it contains are the GC rule and the column family ID already
# stored on this instance.
client.table_admin_client.modify_column_families(
- request={"name": self._table.name, "modifications": [modification]}
+ request={"name": self._table.name, "modifications": [modification]},
+ timeout=DEFAULT,
)
def delete(self):
@@ -324,7 +327,8 @@ def delete(self):
# data it contains are the GC rule and the column family ID already
# stored on this instance.
client.table_admin_client.modify_column_families(
- request={"name": self._table.name, "modifications": [modification]}
+ request={"name": self._table.name, "modifications": [modification]},
+ timeout=DEFAULT,
)
diff --git a/google/cloud/bigtable/data/README.rst b/google/cloud/bigtable/data/README.rst
new file mode 100644
index 000000000..8142cc34d
--- /dev/null
+++ b/google/cloud/bigtable/data/README.rst
@@ -0,0 +1,9 @@
+Async Data Client
+=================
+
+Synchronous API surface and usage examples coming soon
+
+Feedback and bug reports are welcome at cbt-python-client-v3-feedback@google.com,
+or through the Github `issue tracker`_.
+
+.. _issue tracker: https://github.com/googleapis/python-bigtable/issues
diff --git a/google/cloud/bigtable/data/__init__.py b/google/cloud/bigtable/data/__init__.py
new file mode 100644
index 000000000..c18eae683
--- /dev/null
+++ b/google/cloud/bigtable/data/__init__.py
@@ -0,0 +1,109 @@
+# -*- coding: utf-8 -*-
+# Copyright 2023 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.
+#
+from google.cloud.bigtable import gapic_version as package_version
+
+from google.cloud.bigtable.data._async.client import BigtableDataClientAsync
+from google.cloud.bigtable.data._async.client import TableAsync
+from google.cloud.bigtable.data._async.client import AuthorizedViewAsync
+from google.cloud.bigtable.data._async.mutations_batcher import MutationsBatcherAsync
+from google.cloud.bigtable.data._sync_autogen.client import BigtableDataClient
+from google.cloud.bigtable.data._sync_autogen.client import Table
+from google.cloud.bigtable.data._sync_autogen.client import AuthorizedView
+from google.cloud.bigtable.data._sync_autogen.mutations_batcher import MutationsBatcher
+
+from google.cloud.bigtable.data.read_rows_query import ReadRowsQuery
+from google.cloud.bigtable.data.read_rows_query import RowRange
+from google.cloud.bigtable.data.row import Row
+from google.cloud.bigtable.data.row import Cell
+
+from google.cloud.bigtable.data.mutations import Mutation
+from google.cloud.bigtable.data.mutations import RowMutationEntry
+from google.cloud.bigtable.data.mutations import AddToCell
+from google.cloud.bigtable.data.mutations import SetCell
+from google.cloud.bigtable.data.mutations import DeleteRangeFromColumn
+from google.cloud.bigtable.data.mutations import DeleteAllFromFamily
+from google.cloud.bigtable.data.mutations import DeleteAllFromRow
+
+from google.cloud.bigtable.data.exceptions import InvalidChunk
+from google.cloud.bigtable.data.exceptions import FailedMutationEntryError
+from google.cloud.bigtable.data.exceptions import FailedQueryShardError
+
+from google.cloud.bigtable.data.exceptions import RetryExceptionGroup
+from google.cloud.bigtable.data.exceptions import MutationsExceptionGroup
+from google.cloud.bigtable.data.exceptions import ShardedReadRowsExceptionGroup
+from google.cloud.bigtable.data.exceptions import ParameterTypeInferenceFailed
+
+from google.cloud.bigtable.data._helpers import TABLE_DEFAULT
+from google.cloud.bigtable.data._helpers import RowKeySamples
+from google.cloud.bigtable.data._helpers import ShardedQuery
+
+# setup custom CrossSync mappings for library
+from google.cloud.bigtable_v2.services.bigtable.async_client import (
+ BigtableAsyncClient,
+)
+from google.cloud.bigtable.data._async._read_rows import _ReadRowsOperationAsync
+from google.cloud.bigtable.data._async._mutate_rows import _MutateRowsOperationAsync
+
+from google.cloud.bigtable_v2.services.bigtable.client import (
+ BigtableClient,
+)
+from google.cloud.bigtable.data._sync_autogen._read_rows import _ReadRowsOperation
+from google.cloud.bigtable.data._sync_autogen._mutate_rows import _MutateRowsOperation
+
+from google.cloud.bigtable.data._cross_sync import CrossSync
+
+CrossSync.add_mapping("GapicClient", BigtableAsyncClient)
+CrossSync._Sync_Impl.add_mapping("GapicClient", BigtableClient)
+CrossSync.add_mapping("_ReadRowsOperation", _ReadRowsOperationAsync)
+CrossSync._Sync_Impl.add_mapping("_ReadRowsOperation", _ReadRowsOperation)
+CrossSync.add_mapping("_MutateRowsOperation", _MutateRowsOperationAsync)
+CrossSync._Sync_Impl.add_mapping("_MutateRowsOperation", _MutateRowsOperation)
+CrossSync.add_mapping("MutationsBatcher", MutationsBatcherAsync)
+CrossSync._Sync_Impl.add_mapping("MutationsBatcher", MutationsBatcher)
+
+__version__: str = package_version.__version__
+
+__all__ = (
+ "BigtableDataClientAsync",
+ "TableAsync",
+ "AuthorizedViewAsync",
+ "MutationsBatcherAsync",
+ "BigtableDataClient",
+ "Table",
+ "AuthorizedView",
+ "MutationsBatcher",
+ "RowKeySamples",
+ "ReadRowsQuery",
+ "RowRange",
+ "Mutation",
+ "RowMutationEntry",
+ "AddToCell",
+ "SetCell",
+ "DeleteRangeFromColumn",
+ "DeleteAllFromFamily",
+ "DeleteAllFromRow",
+ "Row",
+ "Cell",
+ "InvalidChunk",
+ "FailedMutationEntryError",
+ "FailedQueryShardError",
+ "RetryExceptionGroup",
+ "MutationsExceptionGroup",
+ "ShardedReadRowsExceptionGroup",
+ "ParameterTypeInferenceFailed",
+ "ShardedQuery",
+ "TABLE_DEFAULT",
+)
diff --git a/.github/.OwlBot.yaml b/google/cloud/bigtable/data/_async/__init__.py
similarity index 56%
rename from .github/.OwlBot.yaml
rename to google/cloud/bigtable/data/_async/__init__.py
index fe2f7841a..e13c9acb7 100644
--- a/.github/.OwlBot.yaml
+++ b/google/cloud/bigtable/data/_async/__init__.py
@@ -1,4 +1,4 @@
-# Copyright 2021 Google LLC
+# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -12,17 +12,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-docker:
- image: gcr.io/cloud-devrel-public-resources/owlbot-python:latest
+from google.cloud.bigtable.data._async.client import BigtableDataClientAsync
+from google.cloud.bigtable.data._async.client import TableAsync
-deep-remove-regex:
- - /owl-bot-staging
+from google.cloud.bigtable.data._async.mutations_batcher import MutationsBatcherAsync
-deep-copy-regex:
- - source: /google/bigtable/admin/(v.*)/.*-py/(.*)
- dest: /owl-bot-staging/bigtable_admin/$1/$2
- - source: /google/bigtable/(v.*)/.*-py/(.*)
- dest: /owl-bot-staging/bigtable/$1/$2
-
-begin-after-commit-hash: a21f1091413a260393548c1b2ac44b7347923f08
+__all__ = [
+ "BigtableDataClientAsync",
+ "TableAsync",
+ "MutationsBatcherAsync",
+]
diff --git a/google/cloud/bigtable/data/_async/_mutate_rows.py b/google/cloud/bigtable/data/_async/_mutate_rows.py
new file mode 100644
index 000000000..8e6833bca
--- /dev/null
+++ b/google/cloud/bigtable/data/_async/_mutate_rows.py
@@ -0,0 +1,229 @@
+# Copyright 2024 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.
+#
+from __future__ import annotations
+
+from typing import Sequence, TYPE_CHECKING
+
+from google.api_core import exceptions as core_exceptions
+from google.api_core import retry as retries
+import google.cloud.bigtable_v2.types.bigtable as types_pb
+import google.cloud.bigtable.data.exceptions as bt_exceptions
+from google.cloud.bigtable.data._helpers import _attempt_timeout_generator
+from google.cloud.bigtable.data._helpers import _retry_exception_factory
+
+# mutate_rows requests are limited to this number of mutations
+from google.cloud.bigtable.data.mutations import _MUTATE_ROWS_REQUEST_MUTATION_LIMIT
+from google.cloud.bigtable.data.mutations import _EntryWithProto
+
+from google.cloud.bigtable.data._cross_sync import CrossSync
+
+if TYPE_CHECKING:
+ from google.cloud.bigtable.data.mutations import RowMutationEntry
+
+ if CrossSync.is_async:
+ from google.cloud.bigtable_v2.services.bigtable.async_client import (
+ BigtableAsyncClient as GapicClientType,
+ )
+ from google.cloud.bigtable.data._async.client import ( # type: ignore
+ _DataApiTargetAsync as TargetType,
+ )
+ else:
+ from google.cloud.bigtable_v2.services.bigtable.client import ( # type: ignore
+ BigtableClient as GapicClientType,
+ )
+ from google.cloud.bigtable.data._sync_autogen.client import ( # type: ignore
+ _DataApiTarget as TargetType,
+ )
+
+__CROSS_SYNC_OUTPUT__ = "google.cloud.bigtable.data._sync_autogen._mutate_rows"
+
+
+@CrossSync.convert_class("_MutateRowsOperation")
+class _MutateRowsOperationAsync:
+ """
+ MutateRowsOperation manages the logic of sending a set of row mutations,
+ and retrying on failed entries. It manages this using the _run_attempt
+ function, which attempts to mutate all outstanding entries, and raises
+ _MutateRowsIncomplete if any retryable errors are encountered.
+
+ Errors are exposed as a MutationsExceptionGroup, which contains a list of
+ exceptions organized by the related failed mutation entries.
+
+ Args:
+ gapic_client: the client to use for the mutate_rows call
+ target: the table or view associated with the request
+ mutation_entries: a list of RowMutationEntry objects to send to the server
+ operation_timeout: the timeout to use for the entire operation, in seconds.
+ attempt_timeout: the timeout to use for each mutate_rows attempt, in seconds.
+ If not specified, the request will run until operation_timeout is reached.
+ """
+
+ @CrossSync.convert
+ def __init__(
+ self,
+ gapic_client: GapicClientType,
+ target: TargetType,
+ mutation_entries: list["RowMutationEntry"],
+ operation_timeout: float,
+ attempt_timeout: float | None,
+ retryable_exceptions: Sequence[type[Exception]] = (),
+ ):
+ # check that mutations are within limits
+ total_mutations = sum(len(entry.mutations) for entry in mutation_entries)
+ if total_mutations > _MUTATE_ROWS_REQUEST_MUTATION_LIMIT:
+ raise ValueError(
+ "mutate_rows requests can contain at most "
+ f"{_MUTATE_ROWS_REQUEST_MUTATION_LIMIT} mutations across "
+ f"all entries. Found {total_mutations}."
+ )
+ self._target = target
+ self._gapic_fn = gapic_client.mutate_rows
+ # create predicate for determining which errors are retryable
+ self.is_retryable = retries.if_exception_type(
+ # RPC level errors
+ *retryable_exceptions,
+ # Entry level errors
+ bt_exceptions._MutateRowsIncomplete,
+ )
+ sleep_generator = retries.exponential_sleep_generator(0.01, 2, 60)
+ self._operation = lambda: CrossSync.retry_target(
+ self._run_attempt,
+ self.is_retryable,
+ sleep_generator,
+ operation_timeout,
+ exception_factory=_retry_exception_factory,
+ )
+ # initialize state
+ self.timeout_generator = _attempt_timeout_generator(
+ attempt_timeout, operation_timeout
+ )
+ self.mutations = [_EntryWithProto(m, m._to_pb()) for m in mutation_entries]
+ self.remaining_indices = list(range(len(self.mutations)))
+ self.errors: dict[int, list[Exception]] = {}
+
+ @CrossSync.convert
+ async def start(self):
+ """
+ Start the operation, and run until completion
+
+ Raises:
+ MutationsExceptionGroup: if any mutations failed
+ """
+ try:
+ # trigger mutate_rows
+ await self._operation()
+ except Exception as exc:
+ # exceptions raised by retryable are added to the list of exceptions for all unfinalized mutations
+ incomplete_indices = self.remaining_indices.copy()
+ for idx in incomplete_indices:
+ self._handle_entry_error(idx, exc)
+ finally:
+ # raise exception detailing incomplete mutations
+ all_errors: list[Exception] = []
+ for idx, exc_list in self.errors.items():
+ if len(exc_list) == 0:
+ raise core_exceptions.ClientError(
+ f"Mutation {idx} failed with no associated errors"
+ )
+ elif len(exc_list) == 1:
+ cause_exc = exc_list[0]
+ else:
+ cause_exc = bt_exceptions.RetryExceptionGroup(exc_list)
+ entry = self.mutations[idx].entry
+ all_errors.append(
+ bt_exceptions.FailedMutationEntryError(idx, entry, cause_exc)
+ )
+ if all_errors:
+ raise bt_exceptions.MutationsExceptionGroup(
+ all_errors, len(self.mutations)
+ )
+
+ @CrossSync.convert
+ async def _run_attempt(self):
+ """
+ Run a single attempt of the mutate_rows rpc.
+
+ Raises:
+ _MutateRowsIncomplete: if there are failed mutations eligible for
+ retry after the attempt is complete
+ GoogleAPICallError: if the gapic rpc fails
+ """
+ request_entries = [self.mutations[idx].proto for idx in self.remaining_indices]
+ # track mutations in this request that have not been finalized yet
+ active_request_indices = {
+ req_idx: orig_idx for req_idx, orig_idx in enumerate(self.remaining_indices)
+ }
+ self.remaining_indices = []
+ if not request_entries:
+ # no more mutations. return early
+ return
+ # make gapic request
+ try:
+ result_generator = await self._gapic_fn(
+ request=types_pb.MutateRowsRequest(
+ entries=request_entries,
+ app_profile_id=self._target.app_profile_id,
+ **self._target._request_path,
+ ),
+ timeout=next(self.timeout_generator),
+ retry=None,
+ )
+ async for result_list in result_generator:
+ for result in result_list.entries:
+ # convert sub-request index to global index
+ orig_idx = active_request_indices[result.index]
+ entry_error = core_exceptions.from_grpc_status(
+ result.status.code,
+ result.status.message,
+ details=result.status.details,
+ )
+ if result.status.code != 0:
+ # mutation failed; update error list (and remaining_indices if retryable)
+ self._handle_entry_error(orig_idx, entry_error)
+ elif orig_idx in self.errors:
+ # mutation succeeded; remove from error list
+ del self.errors[orig_idx]
+ # remove processed entry from active list
+ del active_request_indices[result.index]
+ except Exception as exc:
+ # add this exception to list for each mutation that wasn't
+ # already handled, and update remaining_indices if mutation is retryable
+ for idx in active_request_indices.values():
+ self._handle_entry_error(idx, exc)
+ # bubble up exception to be handled by retry wrapper
+ raise
+ # check if attempt succeeded, or needs to be retried
+ if self.remaining_indices:
+ # unfinished work; raise exception to trigger retry
+ raise bt_exceptions._MutateRowsIncomplete
+
+ def _handle_entry_error(self, idx: int, exc: Exception):
+ """
+ Add an exception to the list of exceptions for a given mutation index,
+ and add the index to the list of remaining indices if the exception is
+ retryable.
+
+ Args:
+ idx: the index of the mutation that failed
+ exc: the exception to add to the list
+ """
+ entry = self.mutations[idx].entry
+ self.errors.setdefault(idx, []).append(exc)
+ if (
+ entry.is_idempotent()
+ and self.is_retryable(exc)
+ and idx not in self.remaining_indices
+ ):
+ self.remaining_indices.append(idx)
diff --git a/google/cloud/bigtable/data/_async/_read_rows.py b/google/cloud/bigtable/data/_async/_read_rows.py
new file mode 100644
index 000000000..8787bfa71
--- /dev/null
+++ b/google/cloud/bigtable/data/_async/_read_rows.py
@@ -0,0 +1,365 @@
+# Copyright 2024 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.
+#
+
+from __future__ import annotations
+
+from typing import Sequence, TYPE_CHECKING
+
+from google.cloud.bigtable_v2.types import ReadRowsRequest as ReadRowsRequestPB
+from google.cloud.bigtable_v2.types import ReadRowsResponse as ReadRowsResponsePB
+from google.cloud.bigtable_v2.types import RowSet as RowSetPB
+from google.cloud.bigtable_v2.types import RowRange as RowRangePB
+
+from google.cloud.bigtable.data.row import Row, Cell
+from google.cloud.bigtable.data.read_rows_query import ReadRowsQuery
+from google.cloud.bigtable.data.exceptions import InvalidChunk
+from google.cloud.bigtable.data.exceptions import _RowSetComplete
+from google.cloud.bigtable.data.exceptions import _ResetRow
+from google.cloud.bigtable.data._helpers import _attempt_timeout_generator
+from google.cloud.bigtable.data._helpers import _retry_exception_factory
+
+from google.api_core import retry as retries
+from google.api_core.retry import exponential_sleep_generator
+
+from google.cloud.bigtable.data._cross_sync import CrossSync
+
+if TYPE_CHECKING:
+ if CrossSync.is_async:
+ from google.cloud.bigtable.data._async.client import (
+ _DataApiTargetAsync as TargetType,
+ )
+ else:
+ from google.cloud.bigtable.data._sync_autogen.client import _DataApiTarget as TargetType # type: ignore
+
+__CROSS_SYNC_OUTPUT__ = "google.cloud.bigtable.data._sync_autogen._read_rows"
+
+
+@CrossSync.convert_class("_ReadRowsOperation")
+class _ReadRowsOperationAsync:
+ """
+ ReadRowsOperation handles the logic of merging chunks from a ReadRowsResponse stream
+ into a stream of Row objects.
+
+ ReadRowsOperation.merge_row_response_stream takes in a stream of ReadRowsResponse
+ and turns them into a stream of Row objects using an internal
+ StateMachine.
+
+ ReadRowsOperation(request, client) handles row merging logic end-to-end, including
+ performing retries on stream errors.
+
+ Args:
+ query: The query to execute
+ target: The table or view to send the request to
+ operation_timeout: The total time to allow for the operation, in seconds
+ attempt_timeout: The time to allow for each individual attempt, in seconds
+ retryable_exceptions: A list of exceptions that should trigger a retry
+ """
+
+ __slots__ = (
+ "attempt_timeout_gen",
+ "operation_timeout",
+ "request",
+ "target",
+ "_predicate",
+ "_last_yielded_row_key",
+ "_remaining_count",
+ )
+
+ def __init__(
+ self,
+ query: ReadRowsQuery,
+ target: TargetType,
+ operation_timeout: float,
+ attempt_timeout: float,
+ retryable_exceptions: Sequence[type[Exception]] = (),
+ ):
+ self.attempt_timeout_gen = _attempt_timeout_generator(
+ attempt_timeout, operation_timeout
+ )
+ self.operation_timeout = operation_timeout
+ if isinstance(query, dict):
+ self.request = ReadRowsRequestPB(
+ **query,
+ **target._request_path,
+ app_profile_id=target.app_profile_id,
+ )
+ else:
+ self.request = query._to_pb(target)
+ self.target = target
+ self._predicate = retries.if_exception_type(*retryable_exceptions)
+ self._last_yielded_row_key: bytes | None = None
+ self._remaining_count: int | None = self.request.rows_limit or None
+
+ def start_operation(self) -> CrossSync.Iterable[Row]:
+ """
+ Start the read_rows operation, retrying on retryable errors.
+
+ Yields:
+ Row: The next row in the stream
+ """
+ return CrossSync.retry_target_stream(
+ self._read_rows_attempt,
+ self._predicate,
+ exponential_sleep_generator(0.01, 60, multiplier=2),
+ self.operation_timeout,
+ exception_factory=_retry_exception_factory,
+ )
+
+ def _read_rows_attempt(self) -> CrossSync.Iterable[Row]:
+ """
+ Attempt a single read_rows rpc call.
+ This function is intended to be wrapped by retry logic,
+ which will call this function until it succeeds or
+ a non-retryable error is raised.
+
+ Yields:
+ Row: The next row in the stream
+ """
+ # revise request keys and ranges between attempts
+ if self._last_yielded_row_key is not None:
+ # if this is a retry, try to trim down the request to avoid ones we've already processed
+ try:
+ self.request.rows = self._revise_request_rowset(
+ row_set=self.request.rows,
+ last_seen_row_key=self._last_yielded_row_key,
+ )
+ except _RowSetComplete:
+ # if we've already seen all the rows, we're done
+ return self.merge_rows(None)
+ # revise the limit based on number of rows already yielded
+ if self._remaining_count is not None:
+ self.request.rows_limit = self._remaining_count
+ if self._remaining_count == 0:
+ return self.merge_rows(None)
+ # create and return a new row merger
+ gapic_stream = self.target.client._gapic_client.read_rows(
+ self.request,
+ timeout=next(self.attempt_timeout_gen),
+ retry=None,
+ )
+ chunked_stream = self.chunk_stream(gapic_stream)
+ return self.merge_rows(chunked_stream)
+
+ @CrossSync.convert()
+ async def chunk_stream(
+ self, stream: CrossSync.Awaitable[CrossSync.Iterable[ReadRowsResponsePB]]
+ ) -> CrossSync.Iterable[ReadRowsResponsePB.CellChunk]:
+ """
+ process chunks out of raw read_rows stream
+
+ Args:
+ stream: the raw read_rows stream from the gapic client
+ Yields:
+ ReadRowsResponsePB.CellChunk: the next chunk in the stream
+ """
+ async for resp in await stream:
+ # extract proto from proto-plus wrapper
+ resp = resp._pb
+
+ # handle last_scanned_row_key packets, sent when server
+ # has scanned past the end of the row range
+ if resp.last_scanned_row_key:
+ if (
+ self._last_yielded_row_key is not None
+ and resp.last_scanned_row_key <= self._last_yielded_row_key
+ ):
+ raise InvalidChunk("last scanned out of order")
+ self._last_yielded_row_key = resp.last_scanned_row_key
+
+ current_key = None
+ # process each chunk in the response
+ for c in resp.chunks:
+ if current_key is None:
+ current_key = c.row_key
+ if current_key is None:
+ raise InvalidChunk("first chunk is missing a row key")
+ elif (
+ self._last_yielded_row_key
+ and current_key <= self._last_yielded_row_key
+ ):
+ raise InvalidChunk("row keys should be strictly increasing")
+
+ yield c
+
+ if c.reset_row:
+ current_key = None
+ elif c.commit_row:
+ # update row state after each commit
+ self._last_yielded_row_key = current_key
+ if self._remaining_count is not None:
+ self._remaining_count -= 1
+ if self._remaining_count < 0:
+ raise InvalidChunk("emit count exceeds row limit")
+ current_key = None
+
+ @staticmethod
+ @CrossSync.convert(
+ replace_symbols={"__aiter__": "__iter__", "__anext__": "__next__"},
+ )
+ async def merge_rows(
+ chunks: CrossSync.Iterable[ReadRowsResponsePB.CellChunk] | None,
+ ) -> CrossSync.Iterable[Row]:
+ """
+ Merge chunks into rows
+
+ Args:
+ chunks: the chunk stream to merge
+ Yields:
+ Row: the next row in the stream
+ """
+ if chunks is None:
+ return
+ it = chunks.__aiter__()
+ # For each row
+ while True:
+ try:
+ c = await it.__anext__()
+ except CrossSync.StopIteration:
+ # stream complete
+ return
+ row_key = c.row_key
+
+ if not row_key:
+ raise InvalidChunk("first row chunk is missing key")
+
+ cells = []
+
+ # shared per cell storage
+ family: str | None = None
+ qualifier: bytes | None = None
+
+ try:
+ # for each cell
+ while True:
+ if c.reset_row:
+ raise _ResetRow(c)
+ k = c.row_key
+ f = c.family_name.value
+ q = c.qualifier.value if c.HasField("qualifier") else None
+ if k and k != row_key:
+ raise InvalidChunk("unexpected new row key")
+ if f:
+ family = f
+ if q is not None:
+ qualifier = q
+ else:
+ raise InvalidChunk("new family without qualifier")
+ elif family is None:
+ raise InvalidChunk("missing family")
+ elif q is not None:
+ if family is None:
+ raise InvalidChunk("new qualifier without family")
+ qualifier = q
+ elif qualifier is None:
+ raise InvalidChunk("missing qualifier")
+
+ ts = c.timestamp_micros
+ labels = c.labels if c.labels else []
+ value = c.value
+
+ # merge split cells
+ if c.value_size > 0:
+ buffer = [value]
+ while c.value_size > 0:
+ # throws when premature end
+ c = await it.__anext__()
+
+ t = c.timestamp_micros
+ cl = c.labels
+ k = c.row_key
+ if (
+ c.HasField("family_name")
+ and c.family_name.value != family
+ ):
+ raise InvalidChunk("family changed mid cell")
+ if (
+ c.HasField("qualifier")
+ and c.qualifier.value != qualifier
+ ):
+ raise InvalidChunk("qualifier changed mid cell")
+ if t and t != ts:
+ raise InvalidChunk("timestamp changed mid cell")
+ if cl and cl != labels:
+ raise InvalidChunk("labels changed mid cell")
+ if k and k != row_key:
+ raise InvalidChunk("row key changed mid cell")
+
+ if c.reset_row:
+ raise _ResetRow(c)
+ buffer.append(c.value)
+ value = b"".join(buffer)
+ cells.append(
+ Cell(value, row_key, family, qualifier, ts, list(labels))
+ )
+ if c.commit_row:
+ yield Row(row_key, cells)
+ break
+ c = await it.__anext__()
+ except _ResetRow as e:
+ c = e.chunk
+ if (
+ c.row_key
+ or c.HasField("family_name")
+ or c.HasField("qualifier")
+ or c.timestamp_micros
+ or c.labels
+ or c.value
+ ):
+ raise InvalidChunk("reset row with data")
+ continue
+ except CrossSync.StopIteration:
+ raise InvalidChunk("premature end of stream")
+
+ @staticmethod
+ def _revise_request_rowset(
+ row_set: RowSetPB,
+ last_seen_row_key: bytes,
+ ) -> RowSetPB:
+ """
+ Revise the rows in the request to avoid ones we've already processed.
+
+ Args:
+ row_set: the row set from the request
+ last_seen_row_key: the last row key encountered
+ Returns:
+ RowSetPB: the new rowset after adusting for the last seen key
+ Raises:
+ _RowSetComplete: if there are no rows left to process after the revision
+ """
+ # if user is doing a whole table scan, start a new one with the last seen key
+ if row_set is None or (not row_set.row_ranges and not row_set.row_keys):
+ last_seen = last_seen_row_key
+ return RowSetPB(row_ranges=[RowRangePB(start_key_open=last_seen)])
+ # remove seen keys from user-specific key list
+ adjusted_keys: list[bytes] = [
+ k for k in row_set.row_keys if k > last_seen_row_key
+ ]
+ # adjust ranges to ignore keys before last seen
+ adjusted_ranges: list[RowRangePB] = []
+ for row_range in row_set.row_ranges:
+ end_key = row_range.end_key_closed or row_range.end_key_open or None
+ if end_key is None or end_key > last_seen_row_key:
+ # end range is after last seen key
+ new_range = RowRangePB(row_range)
+ start_key = row_range.start_key_closed or row_range.start_key_open
+ if start_key is None or start_key <= last_seen_row_key:
+ # replace start key with last seen
+ new_range.start_key_open = last_seen_row_key
+ adjusted_ranges.append(new_range)
+ if len(adjusted_keys) == 0 and len(adjusted_ranges) == 0:
+ # if the query is empty after revision, raise an exception
+ # this will avoid an unwanted full table scan
+ raise _RowSetComplete()
+ return RowSetPB(row_keys=adjusted_keys, row_ranges=adjusted_ranges)
diff --git a/google/cloud/bigtable/data/_async/_swappable_channel.py b/google/cloud/bigtable/data/_async/_swappable_channel.py
new file mode 100644
index 000000000..bbc9a0d47
--- /dev/null
+++ b/google/cloud/bigtable/data/_async/_swappable_channel.py
@@ -0,0 +1,139 @@
+# Copyright 2023 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.
+#
+from __future__ import annotations
+
+from typing import Callable
+
+from google.cloud.bigtable.data._cross_sync import CrossSync
+
+from grpc import ChannelConnectivity
+
+if CrossSync.is_async:
+ from grpc.aio import Channel
+else:
+ from grpc import Channel
+
+__CROSS_SYNC_OUTPUT__ = "google.cloud.bigtable.data._sync_autogen._swappable_channel"
+
+
+@CrossSync.convert_class(sync_name="_WrappedChannel", rm_aio=True)
+class _AsyncWrappedChannel(Channel):
+ """
+ A wrapper around a gRPC channel. All methods are passed
+ through to the underlying channel.
+ """
+
+ def __init__(self, channel: Channel):
+ self._channel = channel
+
+ def unary_unary(self, *args, **kwargs):
+ return self._channel.unary_unary(*args, **kwargs)
+
+ def unary_stream(self, *args, **kwargs):
+ return self._channel.unary_stream(*args, **kwargs)
+
+ def stream_unary(self, *args, **kwargs):
+ return self._channel.stream_unary(*args, **kwargs)
+
+ def stream_stream(self, *args, **kwargs):
+ return self._channel.stream_stream(*args, **kwargs)
+
+ async def channel_ready(self):
+ return await self._channel.channel_ready()
+
+ @CrossSync.convert(
+ sync_name="__enter__", replace_symbols={"__aenter__": "__enter__"}
+ )
+ async def __aenter__(self):
+ await self._channel.__aenter__()
+ return self
+
+ @CrossSync.convert(sync_name="__exit__", replace_symbols={"__aexit__": "__exit__"})
+ async def __aexit__(self, exc_type, exc_val, exc_tb):
+ return await self._channel.__aexit__(exc_type, exc_val, exc_tb)
+
+ def get_state(self, try_to_connect: bool = False) -> ChannelConnectivity:
+ return self._channel.get_state(try_to_connect=try_to_connect)
+
+ async def wait_for_state_change(self, last_observed_state):
+ return await self._channel.wait_for_state_change(last_observed_state)
+
+ def __getattr__(self, name):
+ return getattr(self._channel, name)
+
+ async def close(self, grace=None):
+ if CrossSync.is_async:
+ return await self._channel.close(grace=grace)
+ else:
+ # grace not supported by sync version
+ return self._channel.close()
+
+ if not CrossSync.is_async:
+ # add required sync methods
+
+ def subscribe(self, callback, try_to_connect=False):
+ return self._channel.subscribe(callback, try_to_connect)
+
+ def unsubscribe(self, callback):
+ return self._channel.unsubscribe(callback)
+
+
+@CrossSync.convert_class(
+ sync_name="SwappableChannel",
+ replace_symbols={"_AsyncWrappedChannel": "_WrappedChannel"},
+)
+class AsyncSwappableChannel(_AsyncWrappedChannel):
+ """
+ Provides a grpc channel wrapper, that allows the internal channel to be swapped out
+
+ Args:
+ - channel_fn: a nullary function that returns a new channel instance.
+ It should be a partial with all channel configuration arguments built-in
+ """
+
+ def __init__(self, channel_fn: Callable[[], Channel]):
+ self._channel_fn = channel_fn
+ self._channel = channel_fn()
+
+ def create_channel(self) -> Channel:
+ """
+ Create a fresh channel using the stored `channel_fn` partial
+ """
+ new_channel = self._channel_fn()
+ if CrossSync.is_async:
+ # copy over interceptors
+ # this is needed because of how gapic attaches the LoggingClientAIOInterceptor
+ # sync channels add interceptors by wrapping, so this step isn't needed
+ new_channel._unary_unary_interceptors = (
+ self._channel._unary_unary_interceptors
+ )
+ new_channel._unary_stream_interceptors = (
+ self._channel._unary_stream_interceptors
+ )
+ new_channel._stream_unary_interceptors = (
+ self._channel._stream_unary_interceptors
+ )
+ new_channel._stream_stream_interceptors = (
+ self._channel._stream_stream_interceptors
+ )
+ return new_channel
+
+ def swap_channel(self, new_channel: Channel) -> Channel:
+ """
+ Replace the wrapped channel with a new instance. Typically created using `create_channel`
+ """
+ old_channel = self._channel
+ self._channel = new_channel
+ return old_channel
diff --git a/google/cloud/bigtable/data/_async/client.py b/google/cloud/bigtable/data/_async/client.py
new file mode 100644
index 000000000..f86c886f0
--- /dev/null
+++ b/google/cloud/bigtable/data/_async/client.py
@@ -0,0 +1,1890 @@
+# Copyright 2024 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.
+#
+
+from __future__ import annotations
+
+from typing import (
+ cast,
+ Any,
+ AsyncIterable,
+ Callable,
+ Optional,
+ Set,
+ Sequence,
+ TYPE_CHECKING,
+)
+
+import abc
+import time
+import warnings
+import random
+import os
+import concurrent.futures
+
+from functools import partial
+from grpc import Channel
+
+from google.cloud.bigtable.data.execute_query.values import ExecuteQueryValueType
+from google.cloud.bigtable.data.execute_query.metadata import (
+ SqlType,
+ _pb_metadata_to_metadata_types,
+)
+from google.cloud.bigtable.data.execute_query._parameters_formatting import (
+ _format_execute_query_params,
+ _to_param_types,
+)
+from google.cloud.bigtable_v2.services.bigtable.transports.base import (
+ DEFAULT_CLIENT_INFO,
+)
+from google.cloud.bigtable_v2.types.bigtable import PingAndWarmRequest
+from google.cloud.bigtable_v2.types.bigtable import SampleRowKeysRequest
+from google.cloud.bigtable_v2.types.bigtable import MutateRowRequest
+from google.cloud.bigtable_v2.types.bigtable import CheckAndMutateRowRequest
+from google.cloud.bigtable_v2.types.bigtable import ReadModifyWriteRowRequest
+from google.cloud.client import ClientWithProject
+from google.cloud.environment_vars import BIGTABLE_EMULATOR # type: ignore
+from google.api_core import retry as retries
+from google.api_core.exceptions import DeadlineExceeded
+from google.api_core.exceptions import ServiceUnavailable
+from google.api_core.exceptions import Aborted
+from google.api_core.exceptions import Cancelled
+from google.protobuf.message import Message
+from google.protobuf.internal.enum_type_wrapper import EnumTypeWrapper
+
+import google.auth.credentials
+import google.auth._default
+from google.api_core import client_options as client_options_lib
+from google.cloud.bigtable.client import _DEFAULT_BIGTABLE_EMULATOR_CLIENT
+from google.cloud.bigtable.data.row import Row
+from google.cloud.bigtable.data.read_rows_query import ReadRowsQuery
+from google.cloud.bigtable.data.exceptions import FailedQueryShardError
+from google.cloud.bigtable.data.exceptions import ShardedReadRowsExceptionGroup
+
+from google.cloud.bigtable.data._helpers import TABLE_DEFAULT, _align_timeouts
+from google.cloud.bigtable.data._helpers import _WarmedInstanceKey
+from google.cloud.bigtable.data._helpers import _CONCURRENCY_LIMIT
+from google.cloud.bigtable.data._helpers import _retry_exception_factory
+from google.cloud.bigtable.data._helpers import _validate_timeouts
+from google.cloud.bigtable.data._helpers import _get_error_type
+from google.cloud.bigtable.data._helpers import _get_retryable_errors
+from google.cloud.bigtable.data._helpers import _get_timeouts
+from google.cloud.bigtable.data._helpers import _attempt_timeout_generator
+from google.cloud.bigtable.data.mutations import Mutation, RowMutationEntry
+
+from google.cloud.bigtable.data.read_modify_write_rules import ReadModifyWriteRule
+from google.cloud.bigtable.data.row_filters import RowFilter
+from google.cloud.bigtable.data.row_filters import StripValueTransformerFilter
+from google.cloud.bigtable.data.row_filters import CellsRowLimitFilter
+from google.cloud.bigtable.data.row_filters import RowFilterChain
+from google.cloud.bigtable.data._metrics import BigtableClientSideMetricsController
+
+from google.cloud.bigtable.data._cross_sync import CrossSync
+
+if CrossSync.is_async:
+ from grpc.aio import insecure_channel
+ from google.cloud.bigtable_v2.services.bigtable.transports import (
+ BigtableGrpcAsyncIOTransport as TransportType,
+ )
+ from google.cloud.bigtable_v2.services.bigtable import (
+ BigtableAsyncClient as GapicClient,
+ )
+ from google.cloud.bigtable.data._async.mutations_batcher import _MB_SIZE
+ from google.cloud.bigtable.data._async._swappable_channel import (
+ AsyncSwappableChannel as SwappableChannelType,
+ )
+ from google.cloud.bigtable.data._async.metrics_interceptor import (
+ AsyncBigtableMetricsInterceptor as MetricsInterceptorType,
+ )
+else:
+ from typing import Iterable # noqa: F401
+ from grpc import insecure_channel
+ from grpc import intercept_channel
+ from google.cloud.bigtable_v2.services.bigtable.transports import BigtableGrpcTransport as TransportType # type: ignore
+ from google.cloud.bigtable_v2.services.bigtable import BigtableClient as GapicClient # type: ignore
+ from google.cloud.bigtable.data._sync_autogen.mutations_batcher import _MB_SIZE
+ from google.cloud.bigtable.data._sync_autogen._swappable_channel import ( # noqa: F401
+ SwappableChannel as SwappableChannelType,
+ )
+ from google.cloud.bigtable.data._sync_autogen.metrics_interceptor import ( # noqa: F401
+ BigtableMetricsInterceptor as MetricsInterceptorType,
+ )
+
+if TYPE_CHECKING:
+ from google.cloud.bigtable.data._helpers import RowKeySamples
+ from google.cloud.bigtable.data._helpers import ShardedQuery
+
+ if CrossSync.is_async:
+ from google.cloud.bigtable.data._async.mutations_batcher import (
+ MutationsBatcherAsync,
+ )
+ from google.cloud.bigtable.data.execute_query._async.execute_query_iterator import (
+ ExecuteQueryIteratorAsync,
+ )
+ else:
+ from google.cloud.bigtable.data._sync_autogen.mutations_batcher import ( # noqa: F401
+ MutationsBatcher,
+ )
+ from google.cloud.bigtable.data.execute_query._sync_autogen.execute_query_iterator import ( # noqa: F401
+ ExecuteQueryIterator,
+ )
+
+
+__CROSS_SYNC_OUTPUT__ = "google.cloud.bigtable.data._sync_autogen.client"
+
+
+@CrossSync.convert_class(
+ sync_name="BigtableDataClient",
+ add_mapping_for_name="DataClient",
+)
+class BigtableDataClientAsync(ClientWithProject):
+ @CrossSync.convert(
+ docstring_format_vars={
+ "LOOP_MESSAGE": (
+ "Client should be created within an async context (running event loop)",
+ None,
+ ),
+ "RAISE_NO_LOOP": (
+ "RuntimeError: if called outside of an async context (no running event loop)",
+ None,
+ ),
+ }
+ )
+ def __init__(
+ self,
+ *,
+ project: str | None = None,
+ credentials: google.auth.credentials.Credentials | None = None,
+ client_options: dict[str, Any]
+ | "google.api_core.client_options.ClientOptions"
+ | None = None,
+ **kwargs,
+ ):
+ """
+ Create a client instance for the Bigtable Data API
+
+ {LOOP_MESSAGE}
+
+ Args:
+ project: the project which the client acts on behalf of.
+ If not passed, falls back to the default inferred
+ from the environment.
+ credentials:
+ Thehe OAuth2 Credentials to use for this
+ client. If not passed (and if no ``_http`` object is
+ passed), falls back to the default inferred from the
+ environment.
+ client_options:
+ Client options used to set user options
+ on the client. API Endpoint should be set through client_options.
+ Raises:
+ {RAISE_NO_LOOP}
+ """
+ if "pool_size" in kwargs:
+ warnings.warn("pool_size no longer supported")
+ # set up client info headers for veneer library
+ self.client_info = DEFAULT_CLIENT_INFO
+ self.client_info.client_library_version = self._client_version()
+ # parse client options
+ if type(client_options) is dict:
+ client_options = client_options_lib.from_dict(client_options)
+ client_options = cast(
+ Optional[client_options_lib.ClientOptions], client_options
+ )
+ self._emulator_host = os.getenv(BIGTABLE_EMULATOR)
+ if self._emulator_host is not None:
+ warnings.warn(
+ "Connecting to Bigtable emulator at {}".format(self._emulator_host),
+ RuntimeWarning,
+ stacklevel=2,
+ )
+ # use insecure channel if emulator is set
+ if credentials is None:
+ credentials = google.auth.credentials.AnonymousCredentials()
+ if project is None:
+ project = _DEFAULT_BIGTABLE_EMULATOR_CLIENT
+ self._metrics_interceptor = MetricsInterceptorType()
+ # initialize client
+ ClientWithProject.__init__(
+ self,
+ credentials=credentials,
+ project=project,
+ client_options=client_options,
+ )
+ self._gapic_client = GapicClient(
+ credentials=credentials,
+ client_options=client_options,
+ client_info=self.client_info,
+ transport=lambda *args, **kwargs: TransportType(
+ *args, **kwargs, channel=self._build_grpc_channel
+ ),
+ )
+ if (
+ credentials
+ and credentials.universe_domain != self.universe_domain
+ and self._emulator_host is None
+ ):
+ # validate that the universe domain of the credentials matches the
+ # universe domain configured in client_options
+ raise ValueError(
+ f"The configured universe domain ({self.universe_domain}) does "
+ "not match the universe domain found in the credentials "
+ f"({self._credentials.universe_domain}). If you haven't "
+ "configured the universe domain explicitly, `googleapis.com` "
+ "is the default."
+ )
+ self._is_closed = CrossSync.Event()
+ self.transport = cast(TransportType, self._gapic_client.transport)
+ # keep track of active instances to for warmup on channel refresh
+ self._active_instances: Set[_WarmedInstanceKey] = set()
+ # keep track of _DataApiTarget objects associated with each instance
+ # only remove instance from _active_instances when all associated targets are closed
+ self._instance_owners: dict[_WarmedInstanceKey, Set[int]] = {}
+ self._channel_init_time = time.monotonic()
+ self._channel_refresh_task: CrossSync.Task[None] | None = None
+ self._executor: concurrent.futures.ThreadPoolExecutor | None = (
+ concurrent.futures.ThreadPoolExecutor() if not CrossSync.is_async else None
+ )
+ if self._emulator_host is None:
+ # attempt to start background channel refresh tasks
+ try:
+ self._start_background_channel_refresh()
+ except RuntimeError:
+ warnings.warn(
+ f"{self.__class__.__name__} should be started in an "
+ "asyncio event loop. Channel refresh will not be started",
+ RuntimeWarning,
+ stacklevel=2,
+ )
+
+ def _build_grpc_channel(self, *args, **kwargs) -> SwappableChannelType:
+ """
+ This method is called by the gapic transport to create a grpc channel.
+
+ The init arguments passed down are captured in a partial used by SwappableChannel
+ to create new channel instances in the future, as part of the channel refresh logic
+
+ Emulators always use an inseucre channel
+
+ Args:
+ - *args: positional arguments passed by the gapic layer to create a new channel with
+ - **kwargs: keyword arguments passed by the gapic layer to create a new channel with
+ Returns:
+ a custom wrapped swappable channel
+ """
+ create_channel_fn: Callable[[], Channel]
+ if self._emulator_host is not None:
+ # Emulators use insecure channels
+ create_channel_fn = partial(insecure_channel, self._emulator_host)
+ elif CrossSync.is_async:
+ # For async client, use the default create_channel.
+ create_channel_fn = partial(TransportType.create_channel, *args, **kwargs)
+ else:
+ # For sync client, wrap create_channel with interceptors.
+ def sync_create_channel_fn():
+ return intercept_channel(
+ TransportType.create_channel(*args, **kwargs),
+ self._metrics_interceptor,
+ )
+
+ create_channel_fn = sync_create_channel_fn
+
+ # Instantiate SwappableChannelType with the determined creation function.
+ new_channel = SwappableChannelType(create_channel_fn)
+ if CrossSync.is_async:
+ # Attach async interceptors to the channel instance itself.
+ new_channel._unary_unary_interceptors.append(self._metrics_interceptor)
+ new_channel._unary_stream_interceptors.append(self._metrics_interceptor)
+ return new_channel
+
+ @property
+ def universe_domain(self) -> str:
+ """Return the universe domain used by the client instance.
+
+ Returns:
+ str: The universe domain used by the client instance.
+ """
+ return self._gapic_client.universe_domain
+
+ @property
+ def api_endpoint(self) -> str:
+ """Return the API endpoint used by the client instance.
+
+ Returns:
+ str: The API endpoint used by the client instance.
+ """
+ return self._gapic_client.api_endpoint
+
+ @staticmethod
+ def _client_version() -> str:
+ """
+ Helper function to return the client version string for this client
+ """
+ version_str = f"{google.cloud.bigtable.__version__}-data"
+ if CrossSync.is_async:
+ version_str += "-async"
+ return version_str
+
+ @CrossSync.convert(
+ docstring_format_vars={
+ "RAISE_NO_LOOP": (
+ "RuntimeError: if not called in an asyncio event loop",
+ "None",
+ )
+ }
+ )
+ def _start_background_channel_refresh(self) -> None:
+ """
+ Starts a background task to ping and warm grpc channel
+
+ Raises:
+ {RAISE_NO_LOOP}
+ """
+ if (
+ not self._channel_refresh_task
+ and not self._emulator_host
+ and not self._is_closed.is_set()
+ ):
+ # raise error if not in an event loop in async client
+ CrossSync.verify_async_event_loop()
+ self._channel_refresh_task = CrossSync.create_task(
+ self._manage_channel,
+ sync_executor=self._executor,
+ task_name=f"{self.__class__.__name__} channel refresh",
+ )
+
+ @CrossSync.convert
+ async def close(self, timeout: float | None = 2.0):
+ """
+ Cancel all background tasks
+ """
+ self._is_closed.set()
+ if self._channel_refresh_task is not None:
+ self._channel_refresh_task.cancel()
+ await CrossSync.wait([self._channel_refresh_task], timeout=timeout)
+ await self.transport.close()
+ if self._executor:
+ self._executor.shutdown(wait=False)
+ self._channel_refresh_task = None
+
+ @CrossSync.convert
+ async def _ping_and_warm_instances(
+ self,
+ instance_key: _WarmedInstanceKey | None = None,
+ channel: Channel | None = None,
+ ) -> list[BaseException | None]:
+ """
+ Prepares the backend for requests on a channel
+
+ Pings each Bigtable instance registered in `_active_instances` on the client
+
+ Args:
+ instance_key: if provided, only warm the instance associated with the key
+ channel: grpc channel to warm. If none, warms `self.transport.grpc_channel`
+ Returns:
+ list[BaseException | None]: sequence of results or exceptions from the ping requests
+ """
+ channel = channel or self.transport.grpc_channel
+ instance_list = (
+ [instance_key] if instance_key is not None else self._active_instances
+ )
+ ping_rpc = channel.unary_unary(
+ "/google.bigtable.v2.Bigtable/PingAndWarm",
+ request_serializer=PingAndWarmRequest.serialize,
+ )
+ # prepare list of coroutines to run
+ partial_list = [
+ partial(
+ ping_rpc,
+ request={"name": instance_name, "app_profile_id": app_profile_id},
+ metadata=[
+ (
+ "x-goog-request-params",
+ f"name={instance_name}&app_profile_id={app_profile_id}",
+ )
+ ],
+ wait_for_ready=True,
+ )
+ for (instance_name, app_profile_id) in instance_list
+ ]
+ result_list = await CrossSync.gather_partials(
+ partial_list, return_exceptions=True, sync_executor=self._executor
+ )
+ return [r or None for r in result_list]
+
+ def _invalidate_channel_stubs(self):
+ """Helper to reset the cached stubs. Needed when changing out the grpc channel"""
+ self.transport._stubs = {}
+ self.transport._prep_wrapped_messages(self.client_info)
+
+ @CrossSync.convert
+ async def _manage_channel(
+ self,
+ refresh_interval_min: float = 60 * 35,
+ refresh_interval_max: float = 60 * 45,
+ grace_period: float = 60 * 10,
+ ) -> None:
+ """
+ Background task that periodically refreshes and warms a grpc channel
+
+ The backend will automatically close channels after 60 minutes, so
+ `refresh_interval` + `grace_period` should be < 60 minutes
+
+ Runs continuously until the client is closed
+
+ Args:
+ refresh_interval_min: minimum interval before initiating refresh
+ process in seconds. Actual interval will be a random value
+ between `refresh_interval_min` and `refresh_interval_max`
+ refresh_interval_max: maximum interval before initiating refresh
+ process in seconds. Actual interval will be a random value
+ between `refresh_interval_min` and `refresh_interval_max`
+ grace_period: time to allow previous channel to serve existing
+ requests before closing, in seconds
+ """
+ if not isinstance(self.transport.grpc_channel, SwappableChannelType):
+ warnings.warn("Channel does not support auto-refresh.")
+ return
+ super_channel: SwappableChannelType = self.transport.grpc_channel
+ first_refresh = self._channel_init_time + random.uniform(
+ refresh_interval_min, refresh_interval_max
+ )
+ next_sleep = max(first_refresh - time.monotonic(), 0)
+ if next_sleep > 0:
+ # warm the current channel immediately
+ await self._ping_and_warm_instances(channel=super_channel)
+ # continuously refresh the channel every `refresh_interval` seconds
+ while not self._is_closed.is_set():
+ await CrossSync.event_wait(
+ self._is_closed,
+ next_sleep,
+ async_break_early=False, # no need to interrupt sleep. Task will be cancelled on close
+ )
+ if self._is_closed.is_set():
+ # don't refresh if client is closed
+ break
+ start_timestamp = time.monotonic()
+ # prepare new channel for use
+ new_channel = super_channel.create_channel()
+ await self._ping_and_warm_instances(channel=new_channel)
+ # cycle channel out of use, with long grace window before closure
+ old_channel = super_channel.swap_channel(new_channel)
+ self._invalidate_channel_stubs()
+ # give old_channel a chance to complete existing rpcs
+ if grace_period:
+ await CrossSync.event_wait(
+ self._is_closed, grace_period, async_break_early=False
+ )
+ await old_channel.close()
+ # subtract the time spent waiting for the channel to be replaced
+ next_refresh = random.uniform(refresh_interval_min, refresh_interval_max)
+ next_sleep = max(next_refresh - (time.monotonic() - start_timestamp), 0)
+
+ @CrossSync.convert(
+ replace_symbols={
+ "TableAsync": "Table",
+ "ExecuteQueryIteratorAsync": "ExecuteQueryIterator",
+ "_DataApiTargetAsync": "_DataApiTarget",
+ }
+ )
+ async def _register_instance(
+ self,
+ instance_id: str,
+ app_profile_id: Optional[str],
+ owner_id: int,
+ ) -> None:
+ """
+ Registers an instance with the client, and warms the channel for the instance
+ The client will periodically refresh grpc channel used to make
+ requests, and new channels will be warmed for each registered instance
+ Channels will not be refreshed unless at least one instance is registered
+
+ Args:
+ instance_id: id of the instance to register.
+ app_profile_id: id of the app profile calling the instance.
+ owner_id: integer id of the object owning the instance. Owners will be tracked in
+ _instance_owners, and instances will only be unregistered when all
+ owners call _remove_instance_registration. Can be obtained by calling
+ `id` identity funcion, using `id(owner)`
+ """
+ instance_name = self._gapic_client.instance_path(self.project, instance_id)
+ instance_key = _WarmedInstanceKey(instance_name, app_profile_id)
+ self._instance_owners.setdefault(instance_key, set()).add(owner_id)
+ if instance_key not in self._active_instances:
+ self._active_instances.add(instance_key)
+ if self._channel_refresh_task:
+ # refresh tasks already running
+ # call ping and warm on all existing channels
+ await self._ping_and_warm_instances(instance_key)
+ else:
+ # refresh tasks aren't active. start them as background tasks
+ self._start_background_channel_refresh()
+
+ @CrossSync.convert(
+ replace_symbols={
+ "TableAsync": "Table",
+ "ExecuteQueryIteratorAsync": "ExecuteQueryIterator",
+ "_DataApiTargetAsync": "_DataApiTarget",
+ }
+ )
+ def _remove_instance_registration(
+ self,
+ instance_id: str,
+ app_profile_id: Optional[str],
+ owner_id: int,
+ ) -> bool:
+ """
+ Removes an instance from the client's registered instances, to prevent
+ warming new channels for the instance
+
+ If instance_id is not registered, or is still in use by other tables, returns False
+
+ Args:
+ instance_id: id of the instance to remove
+ app_profile_id: id of the app profile calling the instance.
+ owner_id: integer id of the object owning the instance. Can be
+ obtained by the `id` identity funcion, using `id(owner)`.
+ Returns:
+ bool: True if instance was removed, else False
+ """
+ instance_name = self._gapic_client.instance_path(self.project, instance_id)
+ instance_key = _WarmedInstanceKey(instance_name, app_profile_id)
+ owner_list = self._instance_owners.get(instance_key, set())
+ try:
+ owner_list.remove(owner_id)
+ if len(owner_list) == 0:
+ self._active_instances.remove(instance_key)
+ return True
+ except KeyError:
+ return False
+
+ @CrossSync.convert(
+ replace_symbols={"TableAsync": "Table"},
+ docstring_format_vars={
+ "LOOP_MESSAGE": (
+ "Must be created within an async context (running event loop)",
+ "",
+ ),
+ "RAISE_NO_LOOP": (
+ "RuntimeError: if called outside of an async context (no running event loop)",
+ "None",
+ ),
+ },
+ )
+ def get_table(self, instance_id: str, table_id: str, *args, **kwargs) -> TableAsync:
+ """
+ Returns a table instance for making data API requests. All arguments are passed
+ directly to the TableAsync constructor.
+
+ {LOOP_MESSAGE}
+
+ Args:
+ instance_id: The Bigtable instance ID to associate with this client.
+ instance_id is combined with the client's project to fully
+ specify the instance
+ table_id: The ID of the table. table_id is combined with the
+ instance_id and the client's project to fully specify the table
+ app_profile_id: The app profile to associate with requests.
+ https://cloud.google.com/bigtable/docs/app-profiles
+ default_read_rows_operation_timeout: The default timeout for read rows
+ operations, in seconds. If not set, defaults to 600 seconds (10 minutes)
+ default_read_rows_attempt_timeout: The default timeout for individual
+ read rows rpc requests, in seconds. If not set, defaults to 20 seconds
+ default_mutate_rows_operation_timeout: The default timeout for mutate rows
+ operations, in seconds. If not set, defaults to 600 seconds (10 minutes)
+ default_mutate_rows_attempt_timeout: The default timeout for individual
+ mutate rows rpc requests, in seconds. If not set, defaults to 60 seconds
+ default_operation_timeout: The default timeout for all other operations, in
+ seconds. If not set, defaults to 60 seconds
+ default_attempt_timeout: The default timeout for all other individual rpc
+ requests, in seconds. If not set, defaults to 20 seconds
+ default_read_rows_retryable_errors: a list of errors that will be retried
+ if encountered during read_rows and related operations.
+ Defaults to 4 (DeadlineExceeded), 14 (ServiceUnavailable), and 10 (Aborted)
+ default_mutate_rows_retryable_errors: a list of errors that will be retried
+ if encountered during mutate_rows and related operations.
+ Defaults to 4 (DeadlineExceeded) and 14 (ServiceUnavailable)
+ default_retryable_errors: a list of errors that will be retried if
+ encountered during all other operations.
+ Defaults to 4 (DeadlineExceeded) and 14 (ServiceUnavailable)
+ Returns:
+ TableAsync: a table instance for making data API requests
+ Raises:
+ {RAISE_NO_LOOP}
+ """
+ return TableAsync(self, instance_id, table_id, *args, **kwargs)
+
+ @CrossSync.convert(
+ replace_symbols={"AuthorizedViewAsync": "AuthorizedView"},
+ docstring_format_vars={
+ "LOOP_MESSAGE": (
+ "Must be created within an async context (running event loop)",
+ "",
+ ),
+ "RAISE_NO_LOOP": (
+ "RuntimeError: if called outside of an async context (no running event loop)",
+ "None",
+ ),
+ },
+ )
+ def get_authorized_view(
+ self, instance_id: str, table_id: str, authorized_view_id: str, *args, **kwargs
+ ) -> AuthorizedViewAsync:
+ """
+ Returns an authorized view instance for making data API requests. All arguments are passed
+ directly to the AuthorizedViewAsync constructor.
+
+ {LOOP_MESSAGE}
+
+ Args:
+ instance_id: The Bigtable instance ID to associate with this client.
+ instance_id is combined with the client's project to fully
+ specify the instance
+ table_id: The ID of the table. table_id is combined with the
+ instance_id and the client's project to fully specify the table
+ authorized_view_id: The id for the authorized view to use for requests
+ app_profile_id: The app profile to associate with requests.
+ https://cloud.google.com/bigtable/docs/app-profiles
+ default_read_rows_operation_timeout: The default timeout for read rows
+ operations, in seconds. If not set, defaults to Table's value
+ default_read_rows_attempt_timeout: The default timeout for individual
+ read rows rpc requests, in seconds. If not set, defaults Table's value
+ default_mutate_rows_operation_timeout: The default timeout for mutate rows
+ operations, in seconds. If not set, defaults to Table's value
+ default_mutate_rows_attempt_timeout: The default timeout for individual
+ mutate rows rpc requests, in seconds. If not set, defaults Table's value
+ default_operation_timeout: The default timeout for all other operations, in
+ seconds. If not set, defaults to Table's value
+ default_attempt_timeout: The default timeout for all other individual rpc
+ requests, in seconds. If not set, defaults to Table's value
+ default_read_rows_retryable_errors: a list of errors that will be retried
+ if encountered during read_rows and related operations. If not set,
+ defaults to Table's value
+ default_mutate_rows_retryable_errors: a list of errors that will be retried
+ if encountered during mutate_rows and related operations. If not set,
+ defaults to Table's value
+ default_retryable_errors: a list of errors that will be retried if
+ encountered during all other operations. If not set, defaults to
+ Table's value
+ Returns:
+ AuthorizedViewAsync: a table instance for making data API requests
+ Raises:
+ {RAISE_NO_LOOP}
+ """
+ return CrossSync.AuthorizedView(
+ self,
+ instance_id,
+ table_id,
+ authorized_view_id,
+ *args,
+ **kwargs,
+ )
+
+ @CrossSync.convert(
+ replace_symbols={"ExecuteQueryIteratorAsync": "ExecuteQueryIterator"}
+ )
+ async def execute_query(
+ self,
+ query: str,
+ instance_id: str,
+ *,
+ parameters: dict[str, ExecuteQueryValueType] | None = None,
+ parameter_types: dict[str, SqlType.Type] | None = None,
+ app_profile_id: str | None = None,
+ operation_timeout: float = 600,
+ attempt_timeout: float | None = 20,
+ retryable_errors: Sequence[type[Exception]] = (
+ DeadlineExceeded,
+ ServiceUnavailable,
+ Aborted,
+ ),
+ prepare_operation_timeout: float = 60,
+ prepare_attempt_timeout: float | None = 20,
+ prepare_retryable_errors: Sequence[type[Exception]] = (
+ DeadlineExceeded,
+ ServiceUnavailable,
+ ),
+ column_info: dict[str, Message | EnumTypeWrapper] | None = None,
+ ) -> "ExecuteQueryIteratorAsync":
+ """
+ Executes an SQL query on an instance.
+ Returns an iterator to asynchronously stream back columns from selected rows.
+
+ Failed requests within operation_timeout will be retried based on the
+ retryable_errors list until operation_timeout is reached.
+
+ Note that this makes two requests, one to ``PrepareQuery`` and one to ``ExecuteQuery``.
+ These have separate retry configurations. ``ExecuteQuery`` is where the bulk of the
+ work happens.
+
+ Args:
+ query: Query to be run on Bigtable instance. The query can use ``@param``
+ placeholders to use parameter interpolation on the server. Values for all
+ parameters should be provided in ``parameters``. Types of parameters are
+ inferred but should be provided in ``parameter_types`` if the inference is
+ not possible (i.e. when value can be None, an empty list or an empty dict).
+ instance_id: The Bigtable instance ID to perform the query on.
+ instance_id is combined with the client's project to fully
+ specify the instance.
+ parameters: Dictionary with values for all parameters used in the ``query``.
+ parameter_types: Dictionary with types of parameters used in the ``query``.
+ Required to contain entries only for parameters whose type cannot be
+ detected automatically (i.e. the value can be None, an empty list or
+ an empty dict).
+ app_profile_id: The app profile to associate with requests.
+ https://cloud.google.com/bigtable/docs/app-profiles
+ operation_timeout: the time budget for the entire executeQuery operation, in seconds.
+ Failed requests will be retried within the budget.
+ Defaults to 600 seconds.
+ attempt_timeout: the time budget for an individual executeQuery network request, in seconds.
+ If it takes longer than this time to complete, the request will be cancelled with
+ a DeadlineExceeded exception, and a retry will be attempted.
+ Defaults to the 20 seconds.
+ If None, defaults to operation_timeout.
+ retryable_errors: a list of errors that will be retried if encountered during executeQuery.
+ Defaults to 4 (DeadlineExceeded), 14 (ServiceUnavailable), and 10 (Aborted)
+ prepare_operation_timeout: the time budget for the entire prepareQuery operation, in seconds.
+ Failed requests will be retried within the budget.
+ Defaults to 60 seconds.
+ prepare_attempt_timeout: the time budget for an individual prepareQuery network request, in seconds.
+ If it takes longer than this time to complete, the request will be cancelled with
+ a DeadlineExceeded exception, and a retry will be attempted.
+ Defaults to the 20 seconds.
+ If None, defaults to prepare_operation_timeout.
+ prepare_retryable_errors: a list of errors that will be retried if encountered during prepareQuery.
+ Defaults to 4 (DeadlineExceeded) and 14 (ServiceUnavailable)
+ column_info: (Optional) A dictionary mapping column names to Protobuf message classes or EnumTypeWrapper objects.
+ This dictionary provides the necessary type information for deserializing PROTO and
+ ENUM column values from the query results. When an entry is provided
+ for a PROTO or ENUM column, the client library will attempt to deserialize the raw data.
+
+ - For PROTO columns: The value in the dictionary should be the
+ Protobuf Message class (e.g., ``my_pb2.MyMessage``).
+ - For ENUM columns: The value should be the Protobuf EnumTypeWrapper
+ object (e.g., ``my_pb2.MyEnum``).
+
+ Example::
+
+ import my_pb2
+
+ column_info = {
+ "my_proto_column": my_pb2.MyMessage,
+ "my_enum_column": my_pb2.MyEnum
+ }
+
+ If ``column_info`` is not provided, or if a specific column name is not found
+ in the dictionary:
+
+ - PROTO columns will be returned as raw bytes.
+ - ENUM columns will be returned as integers.
+
+ Note for Nested PROTO or ENUM Fields:
+
+ To specify types for PROTO or ENUM fields within STRUCTs or MAPs, use a dot-separated
+ path from the top-level column name.
+
+ - For STRUCTs: ``struct_column_name.field_name``
+ - For MAPs: ``map_column_name.key`` or ``map_column_name.value`` to specify types
+ for the map keys or values, respectively.
+
+ Example::
+
+ import my_pb2
+
+ column_info = {
+ # Top-level column
+ "my_proto_column": my_pb2.MyMessage,
+ "my_enum_column": my_pb2.MyEnum,
+
+ # Nested field in a STRUCT column named 'my_struct'
+ "my_struct.nested_proto_field": my_pb2.OtherMessage,
+ "my_struct.nested_enum_field": my_pb2.AnotherEnum,
+
+ # Nested field in a MAP column named 'my_map'
+ "my_map.key": my_pb2.MapKeyEnum, # If map keys were enums
+ "my_map.value": my_pb2.MapValueMessage,
+
+ # PROTO field inside a STRUCT, where the STRUCT is the value in a MAP column
+ "struct_map.value.nested_proto_field": my_pb2.DeeplyNestedProto,
+ "struct_map.value.nested_enum_field": my_pb2.DeeplyNestedEnum
+ }
+
+ Returns:
+ ExecuteQueryIteratorAsync: an asynchronous iterator that yields rows returned by the query
+ Raises:
+ google.api_core.exceptions.DeadlineExceeded: raised after operation timeout
+ will be chained with a RetryExceptionGroup containing GoogleAPIError exceptions
+ from any retries that failed
+ google.api_core.exceptions.GoogleAPIError: raised if the request encounters an unrecoverable error
+ google.cloud.bigtable.data.exceptions.ParameterTypeInferenceFailed: Raised if
+ a parameter is passed without an explicit type, and the type cannot be infered
+ google.protobuf.message.DecodeError: raised if the deserialization of a PROTO/ENUM value fails.
+ """
+ instance_name = self._gapic_client.instance_path(self.project, instance_id)
+ converted_param_types = _to_param_types(parameters, parameter_types)
+ prepare_request = {
+ "instance_name": instance_name,
+ "query": query,
+ "app_profile_id": app_profile_id,
+ "param_types": converted_param_types,
+ "proto_format": {},
+ }
+ prepare_predicate = retries.if_exception_type(
+ *[_get_error_type(e) for e in prepare_retryable_errors]
+ )
+ prepare_operation_timeout, prepare_attempt_timeout = _align_timeouts(
+ prepare_operation_timeout, prepare_attempt_timeout
+ )
+ prepare_sleep_generator = retries.exponential_sleep_generator(0.01, 2, 60)
+
+ target = partial(
+ self._gapic_client.prepare_query,
+ request=prepare_request,
+ timeout=prepare_attempt_timeout,
+ retry=None,
+ )
+ prepare_result = await CrossSync.retry_target(
+ target,
+ prepare_predicate,
+ prepare_sleep_generator,
+ prepare_operation_timeout,
+ exception_factory=_retry_exception_factory,
+ )
+
+ prepare_metadata = _pb_metadata_to_metadata_types(prepare_result.metadata)
+
+ retryable_excs = [_get_error_type(e) for e in retryable_errors]
+
+ pb_params = _format_execute_query_params(parameters, parameter_types)
+
+ request_body = {
+ "instance_name": instance_name,
+ "app_profile_id": app_profile_id,
+ "prepared_query": prepare_result.prepared_query,
+ "params": pb_params,
+ }
+ operation_timeout, attempt_timeout = _align_timeouts(
+ operation_timeout, attempt_timeout
+ )
+
+ return CrossSync.ExecuteQueryIterator(
+ self,
+ instance_id,
+ app_profile_id,
+ request_body,
+ prepare_metadata,
+ attempt_timeout,
+ operation_timeout,
+ retryable_excs=retryable_excs,
+ column_info=column_info,
+ )
+
+ @CrossSync.convert(sync_name="__enter__")
+ async def __aenter__(self):
+ self._start_background_channel_refresh()
+ return self
+
+ @CrossSync.convert(sync_name="__exit__", replace_symbols={"__aexit__": "__exit__"})
+ async def __aexit__(self, exc_type, exc_val, exc_tb):
+ await self.close()
+ await self._gapic_client.__aexit__(exc_type, exc_val, exc_tb)
+
+
+@CrossSync.convert_class(sync_name="_DataApiTarget")
+class _DataApiTargetAsync(abc.ABC):
+ """
+ Abstract class containing API surface for BigtableDataClient. Should not be created directly
+
+ Can be instantiated as a Table or an AuthorizedView
+ """
+
+ @CrossSync.convert(
+ replace_symbols={"BigtableDataClientAsync": "BigtableDataClient"},
+ docstring_format_vars={
+ "LOOP_MESSAGE": (
+ "Must be created within an async context (running event loop)",
+ "",
+ ),
+ "RAISE_NO_LOOP": (
+ "RuntimeError: if called outside of an async context (no running event loop)",
+ "None",
+ ),
+ },
+ )
+ def __init__(
+ self,
+ client: BigtableDataClientAsync,
+ instance_id: str,
+ table_id: str,
+ app_profile_id: str | None = None,
+ *,
+ default_read_rows_operation_timeout: float = 600,
+ default_read_rows_attempt_timeout: float | None = 20,
+ default_mutate_rows_operation_timeout: float = 600,
+ default_mutate_rows_attempt_timeout: float | None = 60,
+ default_operation_timeout: float = 60,
+ default_attempt_timeout: float | None = 20,
+ default_read_rows_retryable_errors: Sequence[type[Exception]] = (
+ DeadlineExceeded,
+ ServiceUnavailable,
+ Aborted,
+ Cancelled,
+ ),
+ default_mutate_rows_retryable_errors: Sequence[type[Exception]] = (
+ DeadlineExceeded,
+ ServiceUnavailable,
+ ),
+ default_retryable_errors: Sequence[type[Exception]] = (
+ DeadlineExceeded,
+ ServiceUnavailable,
+ ),
+ ):
+ """
+ Initialize a Table instance
+
+ {LOOP_MESSAGE}
+
+ Args:
+ instance_id: The Bigtable instance ID to associate with this client.
+ instance_id is combined with the client's project to fully
+ specify the instance
+ table_id: The ID of the table. table_id is combined with the
+ instance_id and the client's project to fully specify the table
+ app_profile_id: The app profile to associate with requests.
+ https://cloud.google.com/bigtable/docs/app-profiles
+ default_read_rows_operation_timeout: The default timeout for read rows
+ operations, in seconds. If not set, defaults to 600 seconds (10 minutes)
+ default_read_rows_attempt_timeout: The default timeout for individual
+ read rows rpc requests, in seconds. If not set, defaults to 20 seconds
+ default_mutate_rows_operation_timeout: The default timeout for mutate rows
+ operations, in seconds. If not set, defaults to 600 seconds (10 minutes)
+ default_mutate_rows_attempt_timeout: The default timeout for individual
+ mutate rows rpc requests, in seconds. If not set, defaults to 60 seconds
+ default_operation_timeout: The default timeout for all other operations, in
+ seconds. If not set, defaults to 60 seconds
+ default_attempt_timeout: The default timeout for all other individual rpc
+ requests, in seconds. If not set, defaults to 20 seconds
+ default_read_rows_retryable_errors: a list of errors that will be retried
+ if encountered during read_rows and related operations.
+ Defaults to 4 (DeadlineExceeded), 14 (ServiceUnavailable), and 10 (Aborted)
+ default_mutate_rows_retryable_errors: a list of errors that will be retried
+ if encountered during mutate_rows and related operations.
+ Defaults to 4 (DeadlineExceeded) and 14 (ServiceUnavailable)
+ default_retryable_errors: a list of errors that will be retried if
+ encountered during all other operations.
+ Defaults to 4 (DeadlineExceeded) and 14 (ServiceUnavailable)
+ Raises:
+ {RAISE_NO_LOOP}
+ """
+ # NOTE: any changes to the signature of this method should also be reflected
+ # in client.get_table()
+ # validate timeouts
+ _validate_timeouts(
+ default_operation_timeout, default_attempt_timeout, allow_none=True
+ )
+ _validate_timeouts(
+ default_read_rows_operation_timeout,
+ default_read_rows_attempt_timeout,
+ allow_none=True,
+ )
+ _validate_timeouts(
+ default_mutate_rows_operation_timeout,
+ default_mutate_rows_attempt_timeout,
+ allow_none=True,
+ )
+
+ self.client = client
+ self.instance_id = instance_id
+ self.instance_name = self.client._gapic_client.instance_path(
+ self.client.project, instance_id
+ )
+ self.table_id = table_id
+ self.table_name = self.client._gapic_client.table_path(
+ self.client.project, instance_id, table_id
+ )
+ self.app_profile_id: str | None = app_profile_id
+
+ self.default_operation_timeout: float = default_operation_timeout
+ self.default_attempt_timeout: float | None = default_attempt_timeout
+ self.default_read_rows_operation_timeout: float = (
+ default_read_rows_operation_timeout
+ )
+ self.default_read_rows_attempt_timeout: float | None = (
+ default_read_rows_attempt_timeout
+ )
+ self.default_mutate_rows_operation_timeout: float = (
+ default_mutate_rows_operation_timeout
+ )
+ self.default_mutate_rows_attempt_timeout: float | None = (
+ default_mutate_rows_attempt_timeout
+ )
+
+ self.default_read_rows_retryable_errors: Sequence[type[Exception]] = (
+ default_read_rows_retryable_errors or ()
+ )
+ self.default_mutate_rows_retryable_errors: Sequence[type[Exception]] = (
+ default_mutate_rows_retryable_errors or ()
+ )
+ self.default_retryable_errors: Sequence[type[Exception]] = (
+ default_retryable_errors or ()
+ )
+
+ self._metrics = BigtableClientSideMetricsController()
+
+ try:
+ self._register_instance_future = CrossSync.create_task(
+ self.client._register_instance,
+ self.instance_id,
+ self.app_profile_id,
+ id(self),
+ sync_executor=self.client._executor,
+ )
+ except RuntimeError as e:
+ raise RuntimeError(
+ f"{self.__class__.__name__} must be created within an async event loop context."
+ ) from e
+
+ @property
+ @abc.abstractmethod
+ def _request_path(self) -> dict[str, str]:
+ """
+ Used to populate table_name or authorized_view_name for rpc requests, depending on the subclass
+
+ Unimplemented in base class
+ """
+ raise NotImplementedError
+
+ def __str__(self):
+ path_str = list(self._request_path.values())[0] if self._request_path else ""
+ return f"{self.__class__.__name__}<{path_str!r}>"
+
+ @CrossSync.convert(replace_symbols={"AsyncIterable": "Iterable"})
+ async def read_rows_stream(
+ self,
+ query: ReadRowsQuery,
+ *,
+ operation_timeout: float | TABLE_DEFAULT = TABLE_DEFAULT.READ_ROWS,
+ attempt_timeout: float | None | TABLE_DEFAULT = TABLE_DEFAULT.READ_ROWS,
+ retryable_errors: Sequence[type[Exception]]
+ | TABLE_DEFAULT = TABLE_DEFAULT.READ_ROWS,
+ ) -> AsyncIterable[Row]:
+ """
+ Read a set of rows from the table, based on the specified query.
+ Returns an iterator to asynchronously stream back row data.
+
+ Failed requests within operation_timeout will be retried based on the
+ retryable_errors list until operation_timeout is reached.
+
+ Args:
+ query: contains details about which rows to return
+ operation_timeout: the time budget for the entire operation, in seconds.
+ Failed requests will be retried within the budget.
+ Defaults to the Table's default_read_rows_operation_timeout
+ attempt_timeout: the time budget for an individual network request, in seconds.
+ If it takes longer than this time to complete, the request will be cancelled with
+ a DeadlineExceeded exception, and a retry will be attempted.
+ Defaults to the Table's default_read_rows_attempt_timeout.
+ If None, defaults to operation_timeout.
+ retryable_errors: a list of errors that will be retried if encountered.
+ Defaults to the Table's default_read_rows_retryable_errors
+ Returns:
+ AsyncIterable[Row]: an asynchronous iterator that yields rows returned by the query
+ Raises:
+ google.api_core.exceptions.DeadlineExceeded: raised after operation timeout
+ will be chained with a RetryExceptionGroup containing GoogleAPIError exceptions
+ from any retries that failed
+ google.api_core.exceptions.GoogleAPIError: raised if the request encounters an unrecoverable error
+ """
+ operation_timeout, attempt_timeout = _get_timeouts(
+ operation_timeout, attempt_timeout, self
+ )
+ retryable_excs = _get_retryable_errors(retryable_errors, self)
+
+ row_merger = CrossSync._ReadRowsOperation(
+ query,
+ self,
+ operation_timeout=operation_timeout,
+ attempt_timeout=attempt_timeout,
+ retryable_exceptions=retryable_excs,
+ )
+ return row_merger.start_operation()
+
+ @CrossSync.convert
+ async def read_rows(
+ self,
+ query: ReadRowsQuery,
+ *,
+ operation_timeout: float | TABLE_DEFAULT = TABLE_DEFAULT.READ_ROWS,
+ attempt_timeout: float | None | TABLE_DEFAULT = TABLE_DEFAULT.READ_ROWS,
+ retryable_errors: Sequence[type[Exception]]
+ | TABLE_DEFAULT = TABLE_DEFAULT.READ_ROWS,
+ ) -> list[Row]:
+ """
+ Read a set of rows from the table, based on the specified query.
+ Retruns results as a list of Row objects when the request is complete.
+ For streamed results, use read_rows_stream.
+
+ Failed requests within operation_timeout will be retried based on the
+ retryable_errors list until operation_timeout is reached.
+
+ Args:
+ query: contains details about which rows to return
+ operation_timeout: the time budget for the entire operation, in seconds.
+ Failed requests will be retried within the budget.
+ Defaults to the Table's default_read_rows_operation_timeout
+ attempt_timeout: the time budget for an individual network request, in seconds.
+ If it takes longer than this time to complete, the request will be cancelled with
+ a DeadlineExceeded exception, and a retry will be attempted.
+ Defaults to the Table's default_read_rows_attempt_timeout.
+ If None, defaults to operation_timeout.
+ If None, defaults to the Table's default_read_rows_attempt_timeout,
+ or the operation_timeout if that is also None.
+ retryable_errors: a list of errors that will be retried if encountered.
+ Defaults to the Table's default_read_rows_retryable_errors.
+ Returns:
+ list[Row]: a list of Rows returned by the query
+ Raises:
+ google.api_core.exceptions.DeadlineExceeded: raised after operation timeout
+ will be chained with a RetryExceptionGroup containing GoogleAPIError exceptions
+ from any retries that failed
+ google.api_core.exceptions.GoogleAPIError: raised if the request encounters an unrecoverable error
+ """
+ row_generator = await self.read_rows_stream(
+ query,
+ operation_timeout=operation_timeout,
+ attempt_timeout=attempt_timeout,
+ retryable_errors=retryable_errors,
+ )
+ return [row async for row in row_generator]
+
+ @CrossSync.convert
+ async def read_row(
+ self,
+ row_key: str | bytes,
+ *,
+ row_filter: RowFilter | None = None,
+ operation_timeout: float | TABLE_DEFAULT = TABLE_DEFAULT.READ_ROWS,
+ attempt_timeout: float | None | TABLE_DEFAULT = TABLE_DEFAULT.READ_ROWS,
+ retryable_errors: Sequence[type[Exception]]
+ | TABLE_DEFAULT = TABLE_DEFAULT.READ_ROWS,
+ ) -> Row | None:
+ """
+ Read a single row from the table, based on the specified key.
+
+ Failed requests within operation_timeout will be retried based on the
+ retryable_errors list until operation_timeout is reached.
+
+ Args:
+ query: contains details about which rows to return
+ operation_timeout: the time budget for the entire operation, in seconds.
+ Failed requests will be retried within the budget.
+ Defaults to the Table's default_read_rows_operation_timeout
+ attempt_timeout: the time budget for an individual network request, in seconds.
+ If it takes longer than this time to complete, the request will be cancelled with
+ a DeadlineExceeded exception, and a retry will be attempted.
+ Defaults to the Table's default_read_rows_attempt_timeout.
+ If None, defaults to operation_timeout.
+ retryable_errors: a list of errors that will be retried if encountered.
+ Defaults to the Table's default_read_rows_retryable_errors.
+ Returns:
+ Row | None: a Row object if the row exists, otherwise None
+ Raises:
+ google.api_core.exceptions.DeadlineExceeded: raised after operation timeout
+ will be chained with a RetryExceptionGroup containing GoogleAPIError exceptions
+ from any retries that failed
+ google.api_core.exceptions.GoogleAPIError: raised if the request encounters an unrecoverable error
+ """
+ if row_key is None:
+ raise ValueError("row_key must be string or bytes")
+ query = ReadRowsQuery(row_keys=row_key, row_filter=row_filter, limit=1)
+ results = await self.read_rows(
+ query,
+ operation_timeout=operation_timeout,
+ attempt_timeout=attempt_timeout,
+ retryable_errors=retryable_errors,
+ )
+ if len(results) == 0:
+ return None
+ return results[0]
+
+ @CrossSync.convert
+ async def read_rows_sharded(
+ self,
+ sharded_query: ShardedQuery,
+ *,
+ operation_timeout: float | TABLE_DEFAULT = TABLE_DEFAULT.READ_ROWS,
+ attempt_timeout: float | None | TABLE_DEFAULT = TABLE_DEFAULT.READ_ROWS,
+ retryable_errors: Sequence[type[Exception]]
+ | TABLE_DEFAULT = TABLE_DEFAULT.READ_ROWS,
+ ) -> list[Row]:
+ """
+ Runs a sharded query in parallel, then return the results in a single list.
+ Results will be returned in the order of the input queries.
+
+ This function is intended to be run on the results on a query.shard() call.
+ For example::
+
+ table_shard_keys = await table.sample_row_keys()
+ query = ReadRowsQuery(...)
+ shard_queries = query.shard(table_shard_keys)
+ results = await table.read_rows_sharded(shard_queries)
+
+ Args:
+ sharded_query: a sharded query to execute
+ operation_timeout: the time budget for the entire operation, in seconds.
+ Failed requests will be retried within the budget.
+ Defaults to the Table's default_read_rows_operation_timeout
+ attempt_timeout: the time budget for an individual network request, in seconds.
+ If it takes longer than this time to complete, the request will be cancelled with
+ a DeadlineExceeded exception, and a retry will be attempted.
+ Defaults to the Table's default_read_rows_attempt_timeout.
+ If None, defaults to operation_timeout.
+ retryable_errors: a list of errors that will be retried if encountered.
+ Defaults to the Table's default_read_rows_retryable_errors.
+ Returns:
+ list[Row]: a list of Rows returned by the query
+ Raises:
+ ShardedReadRowsExceptionGroup: if any of the queries failed
+ ValueError: if the query_list is empty
+ """
+ if not sharded_query:
+ raise ValueError("empty sharded_query")
+ operation_timeout, attempt_timeout = _get_timeouts(
+ operation_timeout, attempt_timeout, self
+ )
+ # make sure each rpc stays within overall operation timeout
+ rpc_timeout_generator = _attempt_timeout_generator(
+ operation_timeout, operation_timeout
+ )
+
+ # limit the number of concurrent requests using a semaphore
+ concurrency_sem = CrossSync.Semaphore(_CONCURRENCY_LIMIT)
+
+ @CrossSync.convert
+ async def read_rows_with_semaphore(query):
+ async with concurrency_sem:
+ # calculate new timeout based on time left in overall operation
+ shard_timeout = next(rpc_timeout_generator)
+ if shard_timeout <= 0:
+ raise DeadlineExceeded(
+ "Operation timeout exceeded before starting query"
+ )
+ return await self.read_rows(
+ query,
+ operation_timeout=shard_timeout,
+ attempt_timeout=min(attempt_timeout, shard_timeout),
+ retryable_errors=retryable_errors,
+ )
+
+ routine_list = [
+ partial(read_rows_with_semaphore, query) for query in sharded_query
+ ]
+ batch_result = await CrossSync.gather_partials(
+ routine_list,
+ return_exceptions=True,
+ sync_executor=self.client._executor,
+ )
+
+ # collect results and errors
+ error_dict = {}
+ shard_idx = 0
+ results_list = []
+ for result in batch_result:
+ if isinstance(result, Exception):
+ error_dict[shard_idx] = result
+ elif isinstance(result, BaseException):
+ # BaseException not expected; raise immediately
+ raise result
+ else:
+ results_list.extend(result)
+ shard_idx += 1
+ if error_dict:
+ # if any sub-request failed, raise an exception instead of returning results
+ raise ShardedReadRowsExceptionGroup(
+ [
+ FailedQueryShardError(idx, sharded_query[idx], e)
+ for idx, e in error_dict.items()
+ ],
+ results_list,
+ len(sharded_query),
+ )
+ return results_list
+
+ @CrossSync.convert
+ async def row_exists(
+ self,
+ row_key: str | bytes,
+ *,
+ operation_timeout: float | TABLE_DEFAULT = TABLE_DEFAULT.READ_ROWS,
+ attempt_timeout: float | None | TABLE_DEFAULT = TABLE_DEFAULT.READ_ROWS,
+ retryable_errors: Sequence[type[Exception]]
+ | TABLE_DEFAULT = TABLE_DEFAULT.READ_ROWS,
+ ) -> bool:
+ """
+ Return a boolean indicating whether the specified row exists in the table.
+ uses the filters: chain(limit cells per row = 1, strip value)
+
+ Args:
+ row_key: the key of the row to check
+ operation_timeout: the time budget for the entire operation, in seconds.
+ Failed requests will be retried within the budget.
+ Defaults to the Table's default_read_rows_operation_timeout
+ attempt_timeout: the time budget for an individual network request, in seconds.
+ If it takes longer than this time to complete, the request will be cancelled with
+ a DeadlineExceeded exception, and a retry will be attempted.
+ Defaults to the Table's default_read_rows_attempt_timeout.
+ If None, defaults to operation_timeout.
+ retryable_errors: a list of errors that will be retried if encountered.
+ Defaults to the Table's default_read_rows_retryable_errors.
+ Returns:
+ bool: a bool indicating whether the row exists
+ Raises:
+ google.api_core.exceptions.DeadlineExceeded: raised after operation timeout
+ will be chained with a RetryExceptionGroup containing GoogleAPIError exceptions
+ from any retries that failed
+ google.api_core.exceptions.GoogleAPIError: raised if the request encounters an unrecoverable error
+ """
+ if row_key is None:
+ raise ValueError("row_key must be string or bytes")
+
+ strip_filter = StripValueTransformerFilter(flag=True)
+ limit_filter = CellsRowLimitFilter(1)
+ chain_filter = RowFilterChain(filters=[limit_filter, strip_filter])
+ query = ReadRowsQuery(row_keys=row_key, limit=1, row_filter=chain_filter)
+ results = await self.read_rows(
+ query,
+ operation_timeout=operation_timeout,
+ attempt_timeout=attempt_timeout,
+ retryable_errors=retryable_errors,
+ )
+ return len(results) > 0
+
+ @CrossSync.convert
+ async def sample_row_keys(
+ self,
+ *,
+ operation_timeout: float | TABLE_DEFAULT = TABLE_DEFAULT.DEFAULT,
+ attempt_timeout: float | None | TABLE_DEFAULT = TABLE_DEFAULT.DEFAULT,
+ retryable_errors: Sequence[type[Exception]]
+ | TABLE_DEFAULT = TABLE_DEFAULT.DEFAULT,
+ ) -> RowKeySamples:
+ """
+ Return a set of RowKeySamples that delimit contiguous sections of the table of
+ approximately equal size
+
+ RowKeySamples output can be used with ReadRowsQuery.shard() to create a sharded query that
+ can be parallelized across multiple backend nodes read_rows and read_rows_stream
+ requests will call sample_row_keys internally for this purpose when sharding is enabled
+
+ RowKeySamples is simply a type alias for list[tuple[bytes, int]]; a list of
+ row_keys, along with offset positions in the table
+
+ Args:
+ operation_timeout: the time budget for the entire operation, in seconds.
+ Failed requests will be retried within the budget.i
+ Defaults to the Table's default_operation_timeout
+ attempt_timeout: the time budget for an individual network request, in seconds.
+ If it takes longer than this time to complete, the request will be cancelled with
+ a DeadlineExceeded exception, and a retry will be attempted.
+ Defaults to the Table's default_attempt_timeout.
+ If None, defaults to operation_timeout.
+ retryable_errors: a list of errors that will be retried if encountered.
+ Defaults to the Table's default_retryable_errors.
+ Returns:
+ RowKeySamples: a set of RowKeySamples the delimit contiguous sections of the table
+ Raises:
+ google.api_core.exceptions.DeadlineExceeded: raised after operation timeout
+ will be chained with a RetryExceptionGroup containing GoogleAPIError exceptions
+ from any retries that failed
+ google.api_core.exceptions.GoogleAPIError: raised if the request encounters an unrecoverable error
+ """
+ # prepare timeouts
+ operation_timeout, attempt_timeout = _get_timeouts(
+ operation_timeout, attempt_timeout, self
+ )
+ attempt_timeout_gen = _attempt_timeout_generator(
+ attempt_timeout, operation_timeout
+ )
+ # prepare retryable
+ retryable_excs = _get_retryable_errors(retryable_errors, self)
+ predicate = retries.if_exception_type(*retryable_excs)
+
+ sleep_generator = retries.exponential_sleep_generator(0.01, 2, 60)
+
+ @CrossSync.convert
+ async def execute_rpc():
+ results = await self.client._gapic_client.sample_row_keys(
+ request=SampleRowKeysRequest(
+ app_profile_id=self.app_profile_id, **self._request_path
+ ),
+ timeout=next(attempt_timeout_gen),
+ retry=None,
+ )
+ return [(s.row_key, s.offset_bytes) async for s in results]
+
+ return await CrossSync.retry_target(
+ execute_rpc,
+ predicate,
+ sleep_generator,
+ operation_timeout,
+ exception_factory=_retry_exception_factory,
+ )
+
+ @CrossSync.convert(replace_symbols={"MutationsBatcherAsync": "MutationsBatcher"})
+ def mutations_batcher(
+ self,
+ *,
+ flush_interval: float | None = 5,
+ flush_limit_mutation_count: int | None = 1000,
+ flush_limit_bytes: int = 20 * _MB_SIZE,
+ flow_control_max_mutation_count: int = 100_000,
+ flow_control_max_bytes: int = 100 * _MB_SIZE,
+ batch_operation_timeout: float | TABLE_DEFAULT = TABLE_DEFAULT.MUTATE_ROWS,
+ batch_attempt_timeout: float | None | TABLE_DEFAULT = TABLE_DEFAULT.MUTATE_ROWS,
+ batch_retryable_errors: Sequence[type[Exception]]
+ | TABLE_DEFAULT = TABLE_DEFAULT.MUTATE_ROWS,
+ ) -> "MutationsBatcherAsync":
+ """
+ Returns a new mutations batcher instance.
+
+ Can be used to iteratively add mutations that are flushed as a group,
+ to avoid excess network calls
+
+ Args:
+ flush_interval: Automatically flush every flush_interval seconds. If None,
+ a table default will be used
+ flush_limit_mutation_count: Flush immediately after flush_limit_mutation_count
+ mutations are added across all entries. If None, this limit is ignored.
+ flush_limit_bytes: Flush immediately after flush_limit_bytes bytes are added.
+ flow_control_max_mutation_count: Maximum number of inflight mutations.
+ flow_control_max_bytes: Maximum number of inflight bytes.
+ batch_operation_timeout: timeout for each mutate_rows operation, in seconds.
+ Defaults to the Table's default_mutate_rows_operation_timeout
+ batch_attempt_timeout: timeout for each individual request, in seconds.
+ Defaults to the Table's default_mutate_rows_attempt_timeout.
+ If None, defaults to batch_operation_timeout.
+ batch_retryable_errors: a list of errors that will be retried if encountered.
+ Defaults to the Table's default_mutate_rows_retryable_errors.
+ Returns:
+ MutationsBatcherAsync: a MutationsBatcherAsync context manager that can batch requests
+ """
+ return CrossSync.MutationsBatcher(
+ self,
+ flush_interval=flush_interval,
+ flush_limit_mutation_count=flush_limit_mutation_count,
+ flush_limit_bytes=flush_limit_bytes,
+ flow_control_max_mutation_count=flow_control_max_mutation_count,
+ flow_control_max_bytes=flow_control_max_bytes,
+ batch_operation_timeout=batch_operation_timeout,
+ batch_attempt_timeout=batch_attempt_timeout,
+ batch_retryable_errors=batch_retryable_errors,
+ )
+
+ @CrossSync.convert
+ async def mutate_row(
+ self,
+ row_key: str | bytes,
+ mutations: list[Mutation] | Mutation,
+ *,
+ operation_timeout: float | TABLE_DEFAULT = TABLE_DEFAULT.DEFAULT,
+ attempt_timeout: float | None | TABLE_DEFAULT = TABLE_DEFAULT.DEFAULT,
+ retryable_errors: Sequence[type[Exception]]
+ | TABLE_DEFAULT = TABLE_DEFAULT.DEFAULT,
+ ):
+ """
+ Mutates a row atomically.
+
+ Cells already present in the row are left unchanged unless explicitly changed
+ by ``mutation``.
+
+ Idempotent operations (i.e, all mutations have an explicit timestamp) will be
+ retried on server failure. Non-idempotent operations will not.
+
+ Args:
+ row_key: the row to apply mutations to
+ mutations: the set of mutations to apply to the row
+ operation_timeout: the time budget for the entire operation, in seconds.
+ Failed requests will be retried within the budget.
+ Defaults to the Table's default_operation_timeout
+ attempt_timeout: the time budget for an individual network request, in seconds.
+ If it takes longer than this time to complete, the request will be cancelled with
+ a DeadlineExceeded exception, and a retry will be attempted.
+ Defaults to the Table's default_attempt_timeout.
+ If None, defaults to operation_timeout.
+ retryable_errors: a list of errors that will be retried if encountered.
+ Only idempotent mutations will be retried. Defaults to the Table's
+ default_retryable_errors.
+ Raises:
+ google.api_core.exceptions.DeadlineExceeded: raised after operation timeout
+ will be chained with a RetryExceptionGroup containing all
+ GoogleAPIError exceptions from any retries that failed
+ google.api_core.exceptions.GoogleAPIError: raised on non-idempotent operations that cannot be
+ safely retried.
+ ValueError: if invalid arguments are provided
+ """
+ operation_timeout, attempt_timeout = _get_timeouts(
+ operation_timeout, attempt_timeout, self
+ )
+
+ if not mutations:
+ raise ValueError("No mutations provided")
+ mutations_list = mutations if isinstance(mutations, list) else [mutations]
+
+ if all(mutation.is_idempotent() for mutation in mutations_list):
+ # mutations are all idempotent and safe to retry
+ predicate = retries.if_exception_type(
+ *_get_retryable_errors(retryable_errors, self)
+ )
+ else:
+ # mutations should not be retried
+ predicate = retries.if_exception_type()
+
+ sleep_generator = retries.exponential_sleep_generator(0.01, 2, 60)
+
+ target = partial(
+ self.client._gapic_client.mutate_row,
+ request=MutateRowRequest(
+ row_key=row_key.encode("utf-8")
+ if isinstance(row_key, str)
+ else row_key,
+ mutations=[mutation._to_pb() for mutation in mutations_list],
+ app_profile_id=self.app_profile_id,
+ **self._request_path,
+ ),
+ timeout=attempt_timeout,
+ retry=None,
+ )
+ return await CrossSync.retry_target(
+ target,
+ predicate,
+ sleep_generator,
+ operation_timeout,
+ exception_factory=_retry_exception_factory,
+ )
+
+ @CrossSync.convert
+ async def bulk_mutate_rows(
+ self,
+ mutation_entries: list[RowMutationEntry],
+ *,
+ operation_timeout: float | TABLE_DEFAULT = TABLE_DEFAULT.MUTATE_ROWS,
+ attempt_timeout: float | None | TABLE_DEFAULT = TABLE_DEFAULT.MUTATE_ROWS,
+ retryable_errors: Sequence[type[Exception]]
+ | TABLE_DEFAULT = TABLE_DEFAULT.MUTATE_ROWS,
+ ):
+ """
+ Applies mutations for multiple rows in a single batched request.
+
+ Each individual RowMutationEntry is applied atomically, but separate entries
+ may be applied in arbitrary order (even for entries targetting the same row)
+ In total, the row_mutations can contain at most 100000 individual mutations
+ across all entries
+
+ Idempotent entries (i.e., entries with mutations with explicit timestamps)
+ will be retried on failure. Non-idempotent will not, and will reported in a
+ raised exception group
+
+ Args:
+ mutation_entries: the batches of mutations to apply
+ Each entry will be applied atomically, but entries will be applied
+ in arbitrary order
+ operation_timeout: the time budget for the entire operation, in seconds.
+ Failed requests will be retried within the budget.
+ Defaults to the Table's default_mutate_rows_operation_timeout
+ attempt_timeout: the time budget for an individual network request, in seconds.
+ If it takes longer than this time to complete, the request will be cancelled with
+ a DeadlineExceeded exception, and a retry will be attempted.
+ Defaults to the Table's default_mutate_rows_attempt_timeout.
+ If None, defaults to operation_timeout.
+ retryable_errors: a list of errors that will be retried if encountered.
+ Defaults to the Table's default_mutate_rows_retryable_errors
+ Raises:
+ MutationsExceptionGroup: if one or more mutations fails
+ Contains details about any failed entries in .exceptions
+ ValueError: if invalid arguments are provided
+ """
+ operation_timeout, attempt_timeout = _get_timeouts(
+ operation_timeout, attempt_timeout, self
+ )
+ retryable_excs = _get_retryable_errors(retryable_errors, self)
+
+ operation = CrossSync._MutateRowsOperation(
+ self.client._gapic_client,
+ self,
+ mutation_entries,
+ operation_timeout,
+ attempt_timeout,
+ retryable_exceptions=retryable_excs,
+ )
+ await operation.start()
+
+ @CrossSync.convert
+ async def check_and_mutate_row(
+ self,
+ row_key: str | bytes,
+ predicate: RowFilter | None,
+ *,
+ true_case_mutations: Mutation | list[Mutation] | None = None,
+ false_case_mutations: Mutation | list[Mutation] | None = None,
+ operation_timeout: float | TABLE_DEFAULT = TABLE_DEFAULT.DEFAULT,
+ ) -> bool:
+ """
+ Mutates a row atomically based on the output of a predicate filter
+
+ Non-idempotent operation: will not be retried
+
+ Args:
+ row_key: the key of the row to mutate
+ predicate: the filter to be applied to the contents of the specified row.
+ Depending on whether or not any results are yielded,
+ either true_case_mutations or false_case_mutations will be executed.
+ If None, checks that the row contains any values at all.
+ true_case_mutations:
+ Changes to be atomically applied to the specified row if
+ predicate yields at least one cell when
+ applied to row_key. Entries are applied in order,
+ meaning that earlier mutations can be masked by later
+ ones. Must contain at least one entry if
+ false_case_mutations is empty, and at most 100000.
+ false_case_mutations:
+ Changes to be atomically applied to the specified row if
+ predicate_filter does not yield any cells when
+ applied to row_key. Entries are applied in order,
+ meaning that earlier mutations can be masked by later
+ ones. Must contain at least one entry if
+ `true_case_mutations` is empty, and at most 100000.
+ operation_timeout: the time budget for the entire operation, in seconds.
+ Failed requests will not be retried. Defaults to the Table's default_operation_timeout
+ Returns:
+ bool indicating whether the predicate was true or false
+ Raises:
+ google.api_core.exceptions.GoogleAPIError: exceptions from grpc call
+ """
+ operation_timeout, _ = _get_timeouts(operation_timeout, None, self)
+ if true_case_mutations is not None and not isinstance(
+ true_case_mutations, list
+ ):
+ true_case_mutations = [true_case_mutations]
+ true_case_list = [m._to_pb() for m in true_case_mutations or []]
+ if false_case_mutations is not None and not isinstance(
+ false_case_mutations, list
+ ):
+ false_case_mutations = [false_case_mutations]
+ false_case_list = [m._to_pb() for m in false_case_mutations or []]
+ result = await self.client._gapic_client.check_and_mutate_row(
+ request=CheckAndMutateRowRequest(
+ true_mutations=true_case_list,
+ false_mutations=false_case_list,
+ predicate_filter=predicate._to_pb() if predicate is not None else None,
+ row_key=row_key.encode("utf-8")
+ if isinstance(row_key, str)
+ else row_key,
+ app_profile_id=self.app_profile_id,
+ **self._request_path,
+ ),
+ timeout=operation_timeout,
+ retry=None,
+ )
+ return result.predicate_matched
+
+ @CrossSync.convert
+ async def read_modify_write_row(
+ self,
+ row_key: str | bytes,
+ rules: ReadModifyWriteRule | list[ReadModifyWriteRule],
+ *,
+ operation_timeout: float | TABLE_DEFAULT = TABLE_DEFAULT.DEFAULT,
+ ) -> Row:
+ """
+ Reads and modifies a row atomically according to input ReadModifyWriteRules,
+ and returns the contents of all modified cells
+
+ The new value for the timestamp is the greater of the existing timestamp or
+ the current server time.
+
+ Non-idempotent operation: will not be retried
+
+ Args:
+ row_key: the key of the row to apply read/modify/write rules to
+ rules: A rule or set of rules to apply to the row.
+ Rules are applied in order, meaning that earlier rules will affect the
+ results of later ones.
+ operation_timeout: the time budget for the entire operation, in seconds.
+ Failed requests will not be retried.
+ Defaults to the Table's default_operation_timeout.
+ Returns:
+ Row: a Row containing cell data that was modified as part of the operation
+ Raises:
+ google.api_core.exceptions.GoogleAPIError: exceptions from grpc call
+ ValueError: if invalid arguments are provided
+ """
+ operation_timeout, _ = _get_timeouts(operation_timeout, None, self)
+ if operation_timeout <= 0:
+ raise ValueError("operation_timeout must be greater than 0")
+ if rules is not None and not isinstance(rules, list):
+ rules = [rules]
+ if not rules:
+ raise ValueError("rules must contain at least one item")
+ result = await self.client._gapic_client.read_modify_write_row(
+ request=ReadModifyWriteRowRequest(
+ rules=[rule._to_pb() for rule in rules],
+ row_key=row_key.encode("utf-8")
+ if isinstance(row_key, str)
+ else row_key,
+ app_profile_id=self.app_profile_id,
+ **self._request_path,
+ ),
+ timeout=operation_timeout,
+ retry=None,
+ )
+ # construct Row from result
+ return Row._from_pb(result.row)
+
+ @CrossSync.convert
+ async def close(self):
+ """
+ Called to close the Table instance and release any resources held by it.
+ """
+ self._metrics.close()
+ if self._register_instance_future:
+ self._register_instance_future.cancel()
+ self.client._remove_instance_registration(
+ self.instance_id, self.app_profile_id, id(self)
+ )
+
+ @CrossSync.convert(sync_name="__enter__")
+ async def __aenter__(self):
+ """
+ Implement async context manager protocol
+
+ Ensure registration task has time to run, so that
+ grpc channels will be warmed for the specified instance
+ """
+ if self._register_instance_future:
+ await self._register_instance_future
+ return self
+
+ @CrossSync.convert(sync_name="__exit__")
+ async def __aexit__(self, exc_type, exc_val, exc_tb):
+ """
+ Implement async context manager protocol
+
+ Unregister this instance with the client, so that
+ grpc channels will no longer be warmed
+ """
+ await self.close()
+
+
+@CrossSync.convert_class(
+ sync_name="Table",
+ add_mapping_for_name="Table",
+ replace_symbols={"_DataApiTargetAsync": "_DataApiTarget"},
+)
+class TableAsync(_DataApiTargetAsync):
+ """
+ Main Data API surface for interacting with a Bigtable table.
+
+ Table object maintains table_id, and app_profile_id context, and passes them with
+ each call
+ """
+
+ @property
+ def _request_path(self) -> dict[str, str]:
+ return {"table_name": self.table_name}
+
+
+@CrossSync.convert_class(
+ sync_name="AuthorizedView",
+ add_mapping_for_name="AuthorizedView",
+ replace_symbols={"_DataApiTargetAsync": "_DataApiTarget"},
+)
+class AuthorizedViewAsync(_DataApiTargetAsync):
+ """
+ Provides access to an authorized view of a table.
+
+ An authorized view is a subset of a table that you configure to include specific table data.
+ Then you grant access to the authorized view separately from access to the table.
+
+ AuthorizedView object maintains table_id, app_profile_id, and authorized_view_id context,
+ and passed them with each call
+ """
+
+ @CrossSync.convert(
+ docstring_format_vars={
+ "LOOP_MESSAGE": (
+ "Must be created within an async context (running event loop)",
+ "",
+ ),
+ "RAISE_NO_LOOP": (
+ "RuntimeError: if called outside of an async context (no running event loop)",
+ "None",
+ ),
+ }
+ )
+ def __init__(
+ self,
+ client,
+ instance_id,
+ table_id,
+ authorized_view_id,
+ app_profile_id: str | None = None,
+ **kwargs,
+ ):
+ """
+ Initialize an AuthorizedView instance
+
+ {LOOP_MESSAGE}
+
+ Args:
+ instance_id: The Bigtable instance ID to associate with this client.
+ instance_id is combined with the client's project to fully
+ specify the instance
+ table_id: The ID of the table. table_id is combined with the
+ instance_id and the client's project to fully specify the table
+ authorized_view_id: The id for the authorized view to use for requests
+ app_profile_id: The app profile to associate with requests.
+ https://cloud.google.com/bigtable/docs/app-profiles
+ default_read_rows_operation_timeout: The default timeout for read rows
+ operations, in seconds. If not set, defaults to 600 seconds (10 minutes)
+ default_read_rows_attempt_timeout: The default timeout for individual
+ read rows rpc requests, in seconds. If not set, defaults to 20 seconds
+ default_mutate_rows_operation_timeout: The default timeout for mutate rows
+ operations, in seconds. If not set, defaults to 600 seconds (10 minutes)
+ default_mutate_rows_attempt_timeout: The default timeout for individual
+ mutate rows rpc requests, in seconds. If not set, defaults to 60 seconds
+ default_operation_timeout: The default timeout for all other operations, in
+ seconds. If not set, defaults to 60 seconds
+ default_attempt_timeout: The default timeout for all other individual rpc
+ requests, in seconds. If not set, defaults to 20 seconds
+ default_read_rows_retryable_errors: a list of errors that will be retried
+ if encountered during read_rows and related operations.
+ Defaults to 4 (DeadlineExceeded), 14 (ServiceUnavailable), and 10 (Aborted)
+ default_mutate_rows_retryable_errors: a list of errors that will be retried
+ if encountered during mutate_rows and related operations.
+ Defaults to 4 (DeadlineExceeded) and 14 (ServiceUnavailable)
+ default_retryable_errors: a list of errors that will be retried if
+ encountered during all other operations.
+ Defaults to 4 (DeadlineExceeded) and 14 (ServiceUnavailable)
+ Raises:
+ {RAISE_NO_LOOP}
+ """
+ super().__init__(client, instance_id, table_id, app_profile_id, **kwargs)
+ self.authorized_view_id = authorized_view_id
+ self.authorized_view_name: str = self.client._gapic_client.authorized_view_path(
+ self.client.project, instance_id, table_id, authorized_view_id
+ )
+
+ @property
+ def _request_path(self) -> dict[str, str]:
+ return {"authorized_view_name": self.authorized_view_name}
diff --git a/google/cloud/bigtable/data/_async/metrics_interceptor.py b/google/cloud/bigtable/data/_async/metrics_interceptor.py
new file mode 100644
index 000000000..249dcdcc9
--- /dev/null
+++ b/google/cloud/bigtable/data/_async/metrics_interceptor.py
@@ -0,0 +1,172 @@
+# Copyright 2025 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.
+from __future__ import annotations
+
+from typing import Sequence
+
+import time
+from functools import wraps
+
+from google.cloud.bigtable.data._metrics.data_model import ActiveOperationMetric
+from google.cloud.bigtable.data._metrics.data_model import OperationState
+from google.cloud.bigtable.data._metrics.data_model import OperationType
+
+from google.cloud.bigtable.data._cross_sync import CrossSync
+
+if CrossSync.is_async:
+ from grpc.aio import UnaryUnaryClientInterceptor
+ from grpc.aio import UnaryStreamClientInterceptor
+ from grpc.aio import AioRpcError
+else:
+ from grpc import UnaryUnaryClientInterceptor
+ from grpc import UnaryStreamClientInterceptor
+
+
+__CROSS_SYNC_OUTPUT__ = "google.cloud.bigtable.data._sync_autogen.metrics_interceptor"
+
+
+def _with_active_operation(func):
+ """
+ Decorator for interceptor methods to extract the active operation associated with the
+ in-scope contextvars, and pass it to the decorated function.
+ """
+
+ @wraps(func)
+ def wrapper(self, continuation, client_call_details, request):
+ operation: ActiveOperationMetric | None = ActiveOperationMetric.from_context()
+
+ if operation:
+ # start a new attempt if not started
+ if (
+ operation.state == OperationState.CREATED
+ or operation.state == OperationState.BETWEEN_ATTEMPTS
+ ):
+ operation.start_attempt()
+ # wrap continuation in logic to process the operation
+ return func(self, operation, continuation, client_call_details, request)
+ else:
+ # if operation not found, return unwrapped continuation
+ return continuation(client_call_details, request)
+
+ return wrapper
+
+
+@CrossSync.convert
+async def _get_metadata(source) -> dict[str, str | bytes] | None:
+ """Helper to extract metadata from a call or RpcError"""
+ try:
+ metadata: Sequence[tuple[str, str | bytes]]
+ if CrossSync.is_async:
+ # grpc.aio returns metadata in Metadata objects
+ if isinstance(source, AioRpcError):
+ metadata = list(source.trailing_metadata()) + list(
+ source.initial_metadata()
+ )
+ else:
+ metadata = list(await source.trailing_metadata()) + list(
+ await source.initial_metadata()
+ )
+ else:
+ # sync grpc returns metadata as a sequence of tuples
+ metadata = source.trailing_metadata() + source.initial_metadata()
+ # convert metadata to dict format
+ return {k: v for (k, v) in metadata}
+ except Exception:
+ # ignore errors while fetching metadata
+ return None
+
+
+@CrossSync.convert_class(sync_name="BigtableMetricsInterceptor")
+class AsyncBigtableMetricsInterceptor(
+ UnaryUnaryClientInterceptor, UnaryStreamClientInterceptor
+):
+ """
+ An async gRPC interceptor to add client metadata and print server metadata.
+ """
+
+ @CrossSync.convert
+ @_with_active_operation
+ async def intercept_unary_unary(
+ self, operation, continuation, client_call_details, request
+ ):
+ """
+ Interceptor for unary rpcs:
+ - MutateRow
+ - CheckAndMutateRow
+ - ReadModifyWriteRow
+ """
+ metadata = None
+ try:
+ call = await continuation(client_call_details, request)
+ metadata = await _get_metadata(call)
+ return call
+ except Exception as rpc_error:
+ metadata = await _get_metadata(rpc_error)
+ raise rpc_error
+ finally:
+ if metadata is not None:
+ operation.add_response_metadata(metadata)
+
+ @CrossSync.convert
+ @_with_active_operation
+ async def intercept_unary_stream(
+ self, operation, continuation, client_call_details, request
+ ):
+ """
+ Interceptor for streaming rpcs:
+ - ReadRows
+ - MutateRows
+ - SampleRowKeys
+ """
+ try:
+ return self._streaming_generator_wrapper(
+ operation, await continuation(client_call_details, request)
+ )
+ except Exception as rpc_error:
+ # handle errors while intializing stream
+ metadata = await _get_metadata(rpc_error)
+ if metadata is not None:
+ operation.add_response_metadata(metadata)
+ raise rpc_error
+
+ @staticmethod
+ @CrossSync.convert
+ async def _streaming_generator_wrapper(operation, call):
+ """
+ Wrapped generator to be returned by intercept_unary_stream.
+ """
+ # only track has_first response for READ_ROWS
+ has_first_response = (
+ operation.first_response_latency_ns is not None
+ or operation.op_type != OperationType.READ_ROWS
+ )
+ encountered_exc = None
+ try:
+ async for response in call:
+ # record time to first response. Currently only used for READ_ROWs
+ if not has_first_response:
+ operation.first_response_latency_ns = (
+ time.monotonic_ns() - operation.start_time_ns
+ )
+ has_first_response = True
+ yield response
+ except Exception as e:
+ # handle errors while processing stream
+ encountered_exc = e
+ raise
+ finally:
+ if call is not None:
+ metadata = await _get_metadata(encountered_exc or call)
+ if metadata is not None:
+ operation.add_response_metadata(metadata)
diff --git a/google/cloud/bigtable/data/_async/mutations_batcher.py b/google/cloud/bigtable/data/_async/mutations_batcher.py
new file mode 100644
index 000000000..a8e99ea9e
--- /dev/null
+++ b/google/cloud/bigtable/data/_async/mutations_batcher.py
@@ -0,0 +1,536 @@
+# Copyright 2024 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.
+#
+from __future__ import annotations
+
+from typing import Sequence, TYPE_CHECKING, cast
+import atexit
+import warnings
+from collections import deque
+import concurrent.futures
+
+from google.cloud.bigtable.data.exceptions import MutationsExceptionGroup
+from google.cloud.bigtable.data.exceptions import FailedMutationEntryError
+from google.cloud.bigtable.data._helpers import _get_retryable_errors
+from google.cloud.bigtable.data._helpers import _get_timeouts
+from google.cloud.bigtable.data._helpers import TABLE_DEFAULT
+
+from google.cloud.bigtable.data.mutations import (
+ _MUTATE_ROWS_REQUEST_MUTATION_LIMIT,
+)
+from google.cloud.bigtable.data.mutations import Mutation
+
+from google.cloud.bigtable.data._cross_sync import CrossSync
+
+if TYPE_CHECKING:
+ from google.cloud.bigtable.data.mutations import RowMutationEntry
+
+ if CrossSync.is_async:
+ from google.cloud.bigtable.data._async.client import (
+ _DataApiTargetAsync as TargetType,
+ )
+ else:
+ from google.cloud.bigtable.data._sync_autogen.client import _DataApiTarget as TargetType # type: ignore
+
+__CROSS_SYNC_OUTPUT__ = "google.cloud.bigtable.data._sync_autogen.mutations_batcher"
+
+# used to make more readable default values
+_MB_SIZE = 1024 * 1024
+
+
+@CrossSync.convert_class(sync_name="_FlowControl", add_mapping_for_name="_FlowControl")
+class _FlowControlAsync:
+ """
+ Manages flow control for batched mutations. Mutations are registered against
+ the FlowControl object before being sent, which will block if size or count
+ limits have reached capacity. As mutations completed, they are removed from
+ the FlowControl object, which will notify any blocked requests that there
+ is additional capacity.
+
+ Flow limits are not hard limits. If a single mutation exceeds the configured
+ limits, it will be allowed as a single batch when the capacity is available.
+
+ Args:
+ max_mutation_count: maximum number of mutations to send in a single rpc.
+ This corresponds to individual mutations in a single RowMutationEntry.
+ max_mutation_bytes: maximum number of bytes to send in a single rpc.
+ Raises:
+ ValueError: if max_mutation_count or max_mutation_bytes is less than 0
+ """
+
+ def __init__(
+ self,
+ max_mutation_count: int,
+ max_mutation_bytes: int,
+ ):
+ self._max_mutation_count = max_mutation_count
+ self._max_mutation_bytes = max_mutation_bytes
+ if self._max_mutation_count < 1:
+ raise ValueError("max_mutation_count must be greater than 0")
+ if self._max_mutation_bytes < 1:
+ raise ValueError("max_mutation_bytes must be greater than 0")
+ self._capacity_condition = CrossSync.Condition()
+ self._in_flight_mutation_count = 0
+ self._in_flight_mutation_bytes = 0
+
+ def _has_capacity(self, additional_count: int, additional_size: int) -> bool:
+ """
+ Checks if there is capacity to send a new entry with the given size and count
+
+ FlowControl limits are not hard limits. If a single mutation exceeds
+ the configured flow limits, it will be sent in a single batch when
+ previous batches have completed.
+
+ Args:
+ additional_count: number of mutations in the pending entry
+ additional_size: size of the pending entry
+ Returns:
+ bool: True if there is capacity to send the pending entry, False otherwise
+ """
+ # adjust limits to allow overly large mutations
+ acceptable_size = max(self._max_mutation_bytes, additional_size)
+ acceptable_count = max(self._max_mutation_count, additional_count)
+ # check if we have capacity for new mutation
+ new_size = self._in_flight_mutation_bytes + additional_size
+ new_count = self._in_flight_mutation_count + additional_count
+ return new_size <= acceptable_size and new_count <= acceptable_count
+
+ @CrossSync.convert
+ async def remove_from_flow(
+ self, mutations: RowMutationEntry | list[RowMutationEntry]
+ ) -> None:
+ """
+ Removes mutations from flow control. This method should be called once
+ for each mutation that was sent to add_to_flow, after the corresponding
+ operation is complete.
+
+ Args:
+ mutations: mutation or list of mutations to remove from flow control
+ """
+ if not isinstance(mutations, list):
+ mutations = [mutations]
+ total_count = sum(len(entry.mutations) for entry in mutations)
+ total_size = sum(entry.size() for entry in mutations)
+ self._in_flight_mutation_count -= total_count
+ self._in_flight_mutation_bytes -= total_size
+ # notify any blocked requests that there is additional capacity
+ async with self._capacity_condition:
+ self._capacity_condition.notify_all()
+
+ @CrossSync.convert
+ async def add_to_flow(self, mutations: RowMutationEntry | list[RowMutationEntry]):
+ """
+ Generator function that registers mutations with flow control. As mutations
+ are accepted into the flow control, they are yielded back to the caller,
+ to be sent in a batch. If the flow control is at capacity, the generator
+ will block until there is capacity available.
+
+ Args:
+ mutations: list mutations to break up into batches
+ Yields:
+ list[RowMutationEntry]:
+ list of mutations that have reserved space in the flow control.
+ Each batch contains at least one mutation.
+ """
+ if not isinstance(mutations, list):
+ mutations = [mutations]
+ start_idx = 0
+ end_idx = 0
+ while end_idx < len(mutations):
+ start_idx = end_idx
+ batch_mutation_count = 0
+ # fill up batch until we hit capacity
+ async with self._capacity_condition:
+ while end_idx < len(mutations):
+ next_entry = mutations[end_idx]
+ next_size = next_entry.size()
+ next_count = len(next_entry.mutations)
+ if (
+ self._has_capacity(next_count, next_size)
+ # make sure not to exceed per-request mutation count limits
+ and (batch_mutation_count + next_count)
+ <= _MUTATE_ROWS_REQUEST_MUTATION_LIMIT
+ ):
+ # room for new mutation; add to batch
+ end_idx += 1
+ batch_mutation_count += next_count
+ self._in_flight_mutation_bytes += next_size
+ self._in_flight_mutation_count += next_count
+ elif start_idx != end_idx:
+ # we have at least one mutation in the batch, so send it
+ break
+ else:
+ # batch is empty. Block until we have capacity
+ await self._capacity_condition.wait_for(
+ lambda: self._has_capacity(next_count, next_size)
+ )
+ yield mutations[start_idx:end_idx]
+
+
+@CrossSync.convert_class(sync_name="MutationsBatcher")
+class MutationsBatcherAsync:
+ """
+ Allows users to send batches using context manager API.
+
+ Runs mutate_row, mutate_rows, and check_and_mutate_row internally, combining
+ to use as few network requests as required
+
+ Will automatically flush the batcher:
+ - every flush_interval seconds
+ - after queue size reaches flush_limit_mutation_count
+ - after queue reaches flush_limit_bytes
+ - when batcher is closed or destroyed
+
+ Args:
+ table: table or autrhorized_view used to preform rpc calls
+ flush_interval: Automatically flush every flush_interval seconds.
+ If None, no time-based flushing is performed.
+ flush_limit_mutation_count: Flush immediately after flush_limit_mutation_count
+ mutations are added across all entries. If None, this limit is ignored.
+ flush_limit_bytes: Flush immediately after flush_limit_bytes bytes are added.
+ flow_control_max_mutation_count: Maximum number of inflight mutations.
+ flow_control_max_bytes: Maximum number of inflight bytes.
+ batch_operation_timeout: timeout for each mutate_rows operation, in seconds.
+ If TABLE_DEFAULT, defaults to the Table's default_mutate_rows_operation_timeout.
+ batch_attempt_timeout: timeout for each individual request, in seconds.
+ If TABLE_DEFAULT, defaults to the Table's default_mutate_rows_attempt_timeout.
+ If None, defaults to batch_operation_timeout.
+ batch_retryable_errors: a list of errors that will be retried if encountered.
+ Defaults to the Table's default_mutate_rows_retryable_errors.
+ """
+
+ def __init__(
+ self,
+ table: TargetType,
+ *,
+ flush_interval: float | None = 5,
+ flush_limit_mutation_count: int | None = 1000,
+ flush_limit_bytes: int = 20 * _MB_SIZE,
+ flow_control_max_mutation_count: int = 100_000,
+ flow_control_max_bytes: int = 100 * _MB_SIZE,
+ batch_operation_timeout: float | TABLE_DEFAULT = TABLE_DEFAULT.MUTATE_ROWS,
+ batch_attempt_timeout: float | None | TABLE_DEFAULT = TABLE_DEFAULT.MUTATE_ROWS,
+ batch_retryable_errors: Sequence[type[Exception]]
+ | TABLE_DEFAULT = TABLE_DEFAULT.MUTATE_ROWS,
+ ):
+ self._operation_timeout, self._attempt_timeout = _get_timeouts(
+ batch_operation_timeout, batch_attempt_timeout, table
+ )
+ self._retryable_errors: list[type[Exception]] = _get_retryable_errors(
+ batch_retryable_errors, table
+ )
+
+ self._closed = CrossSync.Event()
+ self._target = table
+ self._staged_entries: list[RowMutationEntry] = []
+ self._staged_count, self._staged_bytes = 0, 0
+ self._flow_control = CrossSync._FlowControl(
+ flow_control_max_mutation_count, flow_control_max_bytes
+ )
+ self._flush_limit_bytes = flush_limit_bytes
+ self._flush_limit_count = (
+ flush_limit_mutation_count
+ if flush_limit_mutation_count is not None
+ else float("inf")
+ )
+ # used by sync class to run mutate_rows operations
+ self._sync_rpc_executor = (
+ concurrent.futures.ThreadPoolExecutor(max_workers=8)
+ if not CrossSync.is_async
+ else None
+ )
+ # used by sync class to manage flush_internal tasks
+ self._sync_flush_executor = (
+ concurrent.futures.ThreadPoolExecutor(max_workers=4)
+ if not CrossSync.is_async
+ else None
+ )
+ self._flush_timer = CrossSync.create_task(
+ self._timer_routine, flush_interval, sync_executor=self._sync_flush_executor
+ )
+ self._flush_jobs: set[CrossSync.Future[None]] = set()
+ # MutationExceptionGroup reports number of successful entries along with failures
+ self._entries_processed_since_last_raise: int = 0
+ self._exceptions_since_last_raise: int = 0
+ # keep track of the first and last _exception_list_limit exceptions
+ self._exception_list_limit: int = 10
+ self._oldest_exceptions: list[Exception] = []
+ self._newest_exceptions: deque[Exception] = deque(
+ maxlen=self._exception_list_limit
+ )
+ # clean up on program exit
+ atexit.register(self._on_exit)
+
+ @CrossSync.convert
+ async def _timer_routine(self, interval: float | None) -> None:
+ """
+ Set up a background task to flush the batcher every interval seconds
+
+ If interval is None, an empty future is returned
+
+ Args:
+ flush_interval: Automatically flush every flush_interval seconds.
+ If None, no time-based flushing is performed.
+ """
+ if not interval or interval <= 0:
+ return None
+ while not self._closed.is_set():
+ # wait until interval has passed, or until closed
+ await CrossSync.event_wait(
+ self._closed, timeout=interval, async_break_early=False
+ )
+ if not self._closed.is_set() and self._staged_entries:
+ self._schedule_flush()
+
+ @CrossSync.convert
+ async def append(self, mutation_entry: RowMutationEntry):
+ """
+ Add a new set of mutations to the internal queue
+
+ Args:
+ mutation_entry: new entry to add to flush queue
+ Raises:
+ RuntimeError: if batcher is closed
+ ValueError: if an invalid mutation type is added
+ """
+ # TODO: return a future to track completion of this entry
+ if self._closed.is_set():
+ raise RuntimeError("Cannot append to closed MutationsBatcher")
+ if isinstance(cast(Mutation, mutation_entry), Mutation):
+ raise ValueError(
+ f"invalid mutation type: {type(mutation_entry).__name__}. Only RowMutationEntry objects are supported by batcher"
+ )
+ self._staged_entries.append(mutation_entry)
+ # start a new flush task if limits exceeded
+ self._staged_count += len(mutation_entry.mutations)
+ self._staged_bytes += mutation_entry.size()
+ if (
+ self._staged_count >= self._flush_limit_count
+ or self._staged_bytes >= self._flush_limit_bytes
+ ):
+ self._schedule_flush()
+ # yield to the event loop to allow flush to run
+ await CrossSync.yield_to_event_loop()
+
+ def _schedule_flush(self) -> CrossSync.Future[None] | None:
+ """
+ Update the flush task to include the latest staged entries
+
+ Returns:
+ Future[None] | None:
+ future representing the background task, if started
+ """
+ if self._staged_entries:
+ entries, self._staged_entries = self._staged_entries, []
+ self._staged_count, self._staged_bytes = 0, 0
+ new_task = CrossSync.create_task(
+ self._flush_internal, entries, sync_executor=self._sync_flush_executor
+ )
+ if not new_task.done():
+ self._flush_jobs.add(new_task)
+ new_task.add_done_callback(self._flush_jobs.remove)
+ return new_task
+ return None
+
+ @CrossSync.convert
+ async def _flush_internal(self, new_entries: list[RowMutationEntry]):
+ """
+ Flushes a set of mutations to the server, and updates internal state
+
+ Args:
+ new_entries list of RowMutationEntry objects to flush
+ """
+ # flush new entries
+ in_process_requests: list[CrossSync.Future[list[FailedMutationEntryError]]] = []
+ async for batch in self._flow_control.add_to_flow(new_entries):
+ batch_task = CrossSync.create_task(
+ self._execute_mutate_rows, batch, sync_executor=self._sync_rpc_executor
+ )
+ in_process_requests.append(batch_task)
+ # wait for all inflight requests to complete
+ found_exceptions = await self._wait_for_batch_results(*in_process_requests)
+ # update exception data to reflect any new errors
+ self._entries_processed_since_last_raise += len(new_entries)
+ self._add_exceptions(found_exceptions)
+
+ @CrossSync.convert
+ async def _execute_mutate_rows(
+ self, batch: list[RowMutationEntry]
+ ) -> list[FailedMutationEntryError]:
+ """
+ Helper to execute mutation operation on a batch
+
+ Args:
+ batch: list of RowMutationEntry objects to send to server
+ timeout: timeout in seconds. Used as operation_timeout and attempt_timeout.
+ If not given, will use table defaults
+ Returns:
+ list[FailedMutationEntryError]:
+ list of FailedMutationEntryError objects for mutations that failed.
+ FailedMutationEntryError objects will not contain index information
+ """
+ try:
+ operation = CrossSync._MutateRowsOperation(
+ self._target.client._gapic_client,
+ self._target,
+ batch,
+ operation_timeout=self._operation_timeout,
+ attempt_timeout=self._attempt_timeout,
+ retryable_exceptions=self._retryable_errors,
+ )
+ await operation.start()
+ except MutationsExceptionGroup as e:
+ # strip index information from exceptions, since it is not useful in a batch context
+ for subexc in e.exceptions:
+ subexc.index = None
+ return list(e.exceptions)
+ finally:
+ # mark batch as complete in flow control
+ await self._flow_control.remove_from_flow(batch)
+ return []
+
+ def _add_exceptions(self, excs: list[Exception]):
+ """
+ Add new list of exceptions to internal store. To avoid unbounded memory,
+ the batcher will store the first and last _exception_list_limit exceptions,
+ and discard any in between.
+
+ Args:
+ excs: list of exceptions to add to the internal store
+ """
+ self._exceptions_since_last_raise += len(excs)
+ if excs and len(self._oldest_exceptions) < self._exception_list_limit:
+ # populate oldest_exceptions with found_exceptions
+ addition_count = self._exception_list_limit - len(self._oldest_exceptions)
+ self._oldest_exceptions.extend(excs[:addition_count])
+ excs = excs[addition_count:]
+ if excs:
+ # populate newest_exceptions with remaining found_exceptions
+ self._newest_exceptions.extend(excs[-self._exception_list_limit :])
+
+ def _raise_exceptions(self):
+ """
+ Raise any unreported exceptions from background flush operations
+
+ Raises:
+ MutationsExceptionGroup: exception group with all unreported exceptions
+ """
+ if self._oldest_exceptions or self._newest_exceptions:
+ oldest, self._oldest_exceptions = self._oldest_exceptions, []
+ newest = list(self._newest_exceptions)
+ self._newest_exceptions.clear()
+ entry_count, self._entries_processed_since_last_raise = (
+ self._entries_processed_since_last_raise,
+ 0,
+ )
+ exc_count, self._exceptions_since_last_raise = (
+ self._exceptions_since_last_raise,
+ 0,
+ )
+ raise MutationsExceptionGroup.from_truncated_lists(
+ first_list=oldest,
+ last_list=newest,
+ total_excs=exc_count,
+ entry_count=entry_count,
+ )
+
+ @CrossSync.convert(sync_name="__enter__")
+ async def __aenter__(self):
+ """Allow use of context manager API"""
+ return self
+
+ @CrossSync.convert(sync_name="__exit__")
+ async def __aexit__(self, exc_type, exc, tb):
+ """
+ Allow use of context manager API.
+
+ Flushes the batcher and cleans up resources.
+ """
+ await self.close()
+
+ @property
+ def closed(self) -> bool:
+ """
+ Returns:
+ - True if the batcher is closed, False otherwise
+ """
+ return self._closed.is_set()
+
+ @CrossSync.convert
+ async def close(self):
+ """
+ Flush queue and clean up resources
+ """
+ self._closed.set()
+ self._flush_timer.cancel()
+ self._schedule_flush()
+ # shut down executors
+ if self._sync_flush_executor:
+ with self._sync_flush_executor:
+ self._sync_flush_executor.shutdown(wait=True)
+ if self._sync_rpc_executor:
+ with self._sync_rpc_executor:
+ self._sync_rpc_executor.shutdown(wait=True)
+ await CrossSync.wait([*self._flush_jobs, self._flush_timer])
+ atexit.unregister(self._on_exit)
+ # raise unreported exceptions
+ self._raise_exceptions()
+
+ def _on_exit(self):
+ """
+ Called when program is exited. Raises warning if unflushed mutations remain
+ """
+ if not self._closed.is_set() and self._staged_entries:
+ warnings.warn(
+ f"MutationsBatcher for target {self._target!r} was not closed. "
+ f"{len(self._staged_entries)} Unflushed mutations will not be sent to the server."
+ )
+
+ @staticmethod
+ @CrossSync.convert
+ async def _wait_for_batch_results(
+ *tasks: CrossSync.Future[list[FailedMutationEntryError]]
+ | CrossSync.Future[None],
+ ) -> list[Exception]:
+ """
+ Takes in a list of futures representing _execute_mutate_rows tasks,
+ waits for them to complete, and returns a list of errors encountered.
+
+ Args:
+ *tasks: futures representing _execute_mutate_rows or _flush_internal tasks
+ Returns:
+ list[Exception]:
+ list of Exceptions encountered by any of the tasks. Errors are expected
+ to be FailedMutationEntryError, representing a failed mutation operation.
+ If a task fails with a different exception, it will be included in the
+ output list. Successful tasks will not be represented in the output list.
+ """
+ if not tasks:
+ return []
+ exceptions: list[Exception] = []
+ for task in tasks:
+ if CrossSync.is_async:
+ # futures don't need to be awaited in sync mode
+ await task
+ try:
+ exc_list = task.result()
+ if exc_list:
+ # expect a list of FailedMutationEntryError objects
+ for exc in exc_list:
+ # strip index information
+ exc.index = None
+ exceptions.extend(exc_list)
+ except Exception as e:
+ exceptions.append(e)
+ return exceptions
diff --git a/google/cloud/bigtable/data/_cross_sync/__init__.py b/google/cloud/bigtable/data/_cross_sync/__init__.py
new file mode 100644
index 000000000..77a9ddae9
--- /dev/null
+++ b/google/cloud/bigtable/data/_cross_sync/__init__.py
@@ -0,0 +1,20 @@
+# Copyright 2024 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.
+
+from .cross_sync import CrossSync
+
+
+__all__ = [
+ "CrossSync",
+]
diff --git a/google/cloud/bigtable/data/_cross_sync/_decorators.py b/google/cloud/bigtable/data/_cross_sync/_decorators.py
new file mode 100644
index 000000000..a0dd140dd
--- /dev/null
+++ b/google/cloud/bigtable/data/_cross_sync/_decorators.py
@@ -0,0 +1,448 @@
+# Copyright 2024 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.
+"""
+Contains a set of AstDecorator classes, which define the behavior of CrossSync decorators.
+Each AstDecorator class is used through @CrossSync.
+"""
+from __future__ import annotations
+from typing import TYPE_CHECKING, Iterable
+
+if TYPE_CHECKING:
+ import ast
+ from typing import Callable, Any
+
+
+class AstDecorator:
+ """
+ Helper class for CrossSync decorators used for guiding ast transformations.
+
+ AstDecorators are accessed in two ways:
+ 1. The decorations are used directly as method decorations in the async client,
+ wrapping existing classes and methods
+ 2. The decorations are read back when processing the AST transformations when
+ generating sync code.
+
+ This class allows the same decorator to be used in both contexts.
+
+ Typically, AstDecorators act as a no-op in async code, and the arguments simply
+ provide configuration guidance for the sync code generation.
+ """
+
+ @classmethod
+ def decorator(cls, *args, **kwargs) -> Callable[..., Any]:
+ """
+ Provides a callable that can be used as a decorator function in async code
+
+ AstDecorator.decorate is called by CrossSync when attaching decorators to
+ the CrossSync class.
+
+ This method creates a new instance of the class, using the arguments provided
+ to the decorator, and defers to the async_decorator method of the instance
+ to build the wrapper function.
+
+ Arguments:
+ *args: arguments to the decorator
+ **kwargs: keyword arguments to the decorator
+ """
+ # decorators with no arguments will provide the function to be wrapped
+ # as the first argument. Pull it out if it exists
+ func = None
+ if len(args) == 1 and callable(args[0]):
+ func = args[0]
+ args = args[1:]
+ # create new AstDecorator instance from given decorator arguments
+ new_instance = cls(*args, **kwargs)
+ # build wrapper
+ wrapper = new_instance.async_decorator()
+ if wrapper is None:
+ # if no wrapper, return no-op decorator
+ return func or (lambda f: f)
+ elif func:
+ # if we can, return single wrapped function
+ return wrapper(func)
+ else:
+ # otherwise, return decorator function
+ return wrapper
+
+ def async_decorator(self) -> Callable[..., Any] | None:
+ """
+ Decorator to apply the async_impl decorator to the wrapped function
+
+ Default implementation is a no-op
+ """
+ return None
+
+ def sync_ast_transform(
+ self, wrapped_node: ast.AST, transformers_globals: dict[str, Any]
+ ) -> ast.AST | None:
+ """
+ When this decorator is encountered in the ast during sync generation, this method is called
+ to transform the wrapped node.
+
+ If None is returned, the node will be dropped from the output file.
+
+ Args:
+ wrapped_node: ast node representing the wrapped function or class that is being wrapped
+ transformers_globals: the set of globals() from the transformers module. This is used to access
+ ast transformer classes that live outside the main codebase
+ Returns:
+ transformed ast node, or None if the node should be dropped
+ """
+ return wrapped_node
+
+ @classmethod
+ def get_for_node(cls, node: ast.Call | ast.Attribute | ast.Name) -> "AstDecorator":
+ """
+ Build an AstDecorator instance from an ast decorator node
+
+ The right subclass is found by comparing the string representation of the
+ decorator name to the class name. (Both names are converted to lowercase and
+ underscores are removed for comparison). If a matching subclass is found,
+ a new instance is created with the provided arguments.
+
+ Args:
+ node: ast.Call node representing the decorator
+ Returns:
+ AstDecorator instance corresponding to the decorator
+ Raises:
+ ValueError: if the decorator cannot be parsed
+ """
+ import ast
+
+ # expect decorators in format @CrossSync.
+ # (i.e. should be an ast.Call or an ast.Attribute)
+ root_attr = node.func if isinstance(node, ast.Call) else node
+ if not isinstance(root_attr, ast.Attribute):
+ raise ValueError("Unexpected decorator format")
+ # extract the module and decorator names
+ if "CrossSync" in ast.dump(root_attr):
+ decorator_name = root_attr.attr
+ got_kwargs: dict[str, Any] = (
+ {str(kw.arg): cls._convert_ast_to_py(kw.value) for kw in node.keywords}
+ if hasattr(node, "keywords")
+ else {}
+ )
+ got_args = (
+ [cls._convert_ast_to_py(arg) for arg in node.args]
+ if hasattr(node, "args")
+ else []
+ )
+ # convert to standardized representation
+ formatted_name = decorator_name.replace("_", "").lower()
+ for subclass in cls.get_subclasses():
+ if subclass.__name__.lower() == formatted_name:
+ return subclass(*got_args, **got_kwargs)
+ raise ValueError(f"Unknown decorator encountered: {decorator_name}")
+ else:
+ raise ValueError("Not a CrossSync decorator")
+
+ @classmethod
+ def get_subclasses(cls) -> Iterable[type["AstDecorator"]]:
+ """
+ Get all subclasses of AstDecorator
+
+ Returns:
+ list of all subclasses of AstDecorator
+ """
+ for subclass in cls.__subclasses__():
+ yield from subclass.get_subclasses()
+ yield subclass
+
+ @classmethod
+ def _convert_ast_to_py(cls, ast_node: ast.expr | None) -> Any:
+ """
+ Helper to convert ast primitives to python primitives. Used when unwrapping arguments
+ """
+ import ast
+
+ if ast_node is None:
+ return None
+ if isinstance(ast_node, ast.Constant):
+ return ast_node.value
+ if isinstance(ast_node, ast.List):
+ return [cls._convert_ast_to_py(node) for node in ast_node.elts]
+ if isinstance(ast_node, ast.Tuple):
+ return tuple(cls._convert_ast_to_py(node) for node in ast_node.elts)
+ if isinstance(ast_node, ast.Dict):
+ return {
+ cls._convert_ast_to_py(k): cls._convert_ast_to_py(v)
+ for k, v in zip(ast_node.keys, ast_node.values)
+ }
+ # unsupported node type
+ return ast_node
+
+
+class ConvertClass(AstDecorator):
+ """
+ Class decorator for guiding generation of sync classes
+
+ Args:
+ sync_name: use a new name for the sync class
+ replace_symbols: a dict of symbols and replacements to use when generating sync class
+ docstring_format_vars: a dict of variables to replace in the docstring
+ rm_aio: if True, automatically strip all asyncio keywords from method. If false,
+ only keywords wrapped in CrossSync.rm_aio() calls to be removed.
+ add_mapping_for_name: when given, will add a new attribute to CrossSync,
+ so the original class and its sync version can be accessed from CrossSync.
+ """
+
+ def __init__(
+ self,
+ sync_name: str | None = None,
+ *,
+ replace_symbols: dict[str, str] | None = None,
+ docstring_format_vars: dict[str, tuple[str | None, str | None]] | None = None,
+ rm_aio: bool = False,
+ add_mapping_for_name: str | None = None,
+ ):
+ self.sync_name = sync_name
+ self.replace_symbols = replace_symbols
+ docstring_format_vars = docstring_format_vars or {}
+ self.async_docstring_format_vars = {
+ k: v[0] or "" for k, v in docstring_format_vars.items()
+ }
+ self.sync_docstring_format_vars = {
+ k: v[1] or "" for k, v in docstring_format_vars.items()
+ }
+ self.rm_aio = rm_aio
+ self.add_mapping_for_name = add_mapping_for_name
+
+ def async_decorator(self):
+ """
+ Use async decorator as a hook to update CrossSync mappings
+ """
+ from .cross_sync import CrossSync
+
+ if not self.add_mapping_for_name and not self.async_docstring_format_vars:
+ # return None if no changes needed
+ return None
+
+ new_mapping = self.add_mapping_for_name
+
+ def decorator(cls):
+ if new_mapping:
+ CrossSync.add_mapping(new_mapping, cls)
+ if self.async_docstring_format_vars:
+ cls.__doc__ = cls.__doc__.format(**self.async_docstring_format_vars)
+ return cls
+
+ return decorator
+
+ def sync_ast_transform(self, wrapped_node, transformers_globals):
+ """
+ Transform async class into sync copy
+ """
+ import ast
+ import copy
+
+ # copy wrapped node
+ wrapped_node = copy.deepcopy(wrapped_node)
+ # update name
+ if self.sync_name:
+ wrapped_node.name = self.sync_name
+ # strip CrossSync decorators
+ if hasattr(wrapped_node, "decorator_list"):
+ wrapped_node.decorator_list = [
+ d for d in wrapped_node.decorator_list if "CrossSync" not in ast.dump(d)
+ ]
+ else:
+ wrapped_node.decorator_list = []
+ # strip async keywords if specified
+ if self.rm_aio:
+ wrapped_node = transformers_globals["AsyncToSync"]().visit(wrapped_node)
+ # add mapping decorator if needed
+ if self.add_mapping_for_name:
+ wrapped_node.decorator_list.append(
+ ast.Call(
+ func=ast.Attribute(
+ value=ast.Name(id="CrossSync", ctx=ast.Load()),
+ attr="add_mapping_decorator",
+ ctx=ast.Load(),
+ ),
+ args=[
+ ast.Constant(value=self.add_mapping_for_name),
+ ],
+ keywords=[],
+ )
+ )
+ # replace symbols if specified
+ if self.replace_symbols:
+ wrapped_node = transformers_globals["SymbolReplacer"](
+ self.replace_symbols
+ ).visit(wrapped_node)
+ # update docstring if specified
+ if self.sync_docstring_format_vars:
+ docstring = ast.get_docstring(wrapped_node)
+ if docstring:
+ wrapped_node.body[0].value = ast.Constant(
+ value=docstring.format(**self.sync_docstring_format_vars)
+ )
+ return wrapped_node
+
+
+class Convert(ConvertClass):
+ """
+ Method decorator to mark async methods to be converted to sync methods
+
+ Args:
+ sync_name: use a new name for the sync method
+ replace_symbols: a dict of symbols and replacements to use when generating sync method
+ docstring_format_vars: a dict of variables to replace in the docstring
+ rm_aio: if True, automatically strip all asyncio keywords from method. If False,
+ only the signature `async def` is stripped. Other keywords must be wrapped in
+ CrossSync.rm_aio() calls to be removed.
+ """
+
+ def __init__(
+ self,
+ sync_name: str | None = None,
+ *,
+ replace_symbols: dict[str, str] | None = None,
+ docstring_format_vars: dict[str, tuple[str | None, str | None]] | None = None,
+ rm_aio: bool = True,
+ ):
+ super().__init__(
+ sync_name=sync_name,
+ replace_symbols=replace_symbols,
+ docstring_format_vars=docstring_format_vars,
+ rm_aio=rm_aio,
+ add_mapping_for_name=None,
+ )
+
+ def sync_ast_transform(self, wrapped_node, transformers_globals):
+ """
+ Transform async method into sync
+ """
+ import ast
+
+ # replace async function with sync function
+ converted = ast.copy_location(
+ ast.FunctionDef(
+ wrapped_node.name,
+ wrapped_node.args,
+ wrapped_node.body,
+ wrapped_node.decorator_list
+ if hasattr(wrapped_node, "decorator_list")
+ else [],
+ wrapped_node.returns if hasattr(wrapped_node, "returns") else None,
+ ),
+ wrapped_node,
+ )
+ # transform based on arguments
+ return super().sync_ast_transform(converted, transformers_globals)
+
+
+class Drop(AstDecorator):
+ """
+ Method decorator to drop methods or classes from the sync output
+ """
+
+ def sync_ast_transform(self, wrapped_node, transformers_globals):
+ """
+ Drop from sync output
+ """
+ return None
+
+
+class Pytest(AstDecorator):
+ """
+ Used in place of pytest.mark.asyncio to mark tests
+
+ When generating sync version, also runs rm_aio to remove async keywords from
+ entire test function
+
+ Args:
+ rm_aio: if True, automatically strip all asyncio keywords from test code.
+ Defaults to True, to simplify test code generation.
+ """
+
+ def __init__(self, rm_aio=True):
+ self.rm_aio = rm_aio
+
+ def async_decorator(self):
+ import pytest
+
+ return pytest.mark.asyncio
+
+ def sync_ast_transform(self, wrapped_node, transformers_globals):
+ """
+ convert async to sync
+ """
+ import ast
+
+ # always convert method to sync
+ converted = ast.copy_location(
+ ast.FunctionDef(
+ wrapped_node.name,
+ wrapped_node.args,
+ wrapped_node.body,
+ wrapped_node.decorator_list
+ if hasattr(wrapped_node, "decorator_list")
+ else [],
+ wrapped_node.returns if hasattr(wrapped_node, "returns") else None,
+ ),
+ wrapped_node,
+ )
+ # convert entire body to sync if rm_aio is set
+ if self.rm_aio:
+ converted = transformers_globals["AsyncToSync"]().visit(converted)
+ return converted
+
+
+class PytestFixture(AstDecorator):
+ """
+ Used in place of pytest.fixture or pytest.mark.asyncio to mark fixtures
+
+ Args:
+ *args: all arguments to pass to pytest.fixture
+ **kwargs: all keyword arguments to pass to pytest.fixture
+ """
+
+ def __init__(self, *args, **kwargs):
+ self._args = args
+ self._kwargs = kwargs
+
+ def async_decorator(self):
+ import pytest_asyncio # type: ignore
+
+ return lambda f: pytest_asyncio.fixture(*self._args, **self._kwargs)(f)
+
+ def sync_ast_transform(self, wrapped_node, transformers_globals):
+ import ast
+ import copy
+
+ arg_nodes = [
+ a if isinstance(a, ast.expr) else ast.Constant(value=a) for a in self._args
+ ]
+ kwarg_nodes = []
+ for k, v in self._kwargs.items():
+ if not isinstance(v, ast.expr):
+ v = ast.Constant(value=v)
+ kwarg_nodes.append(ast.keyword(arg=k, value=v))
+
+ new_node = copy.deepcopy(wrapped_node)
+ if not hasattr(new_node, "decorator_list"):
+ new_node.decorator_list = []
+ new_node.decorator_list.append(
+ ast.Call(
+ func=ast.Attribute(
+ value=ast.Name(id="pytest", ctx=ast.Load()),
+ attr="fixture",
+ ctx=ast.Load(),
+ ),
+ args=arg_nodes,
+ keywords=kwarg_nodes,
+ )
+ )
+ return new_node
diff --git a/google/cloud/bigtable/data/_cross_sync/_mapping_meta.py b/google/cloud/bigtable/data/_cross_sync/_mapping_meta.py
new file mode 100644
index 000000000..5312708cc
--- /dev/null
+++ b/google/cloud/bigtable/data/_cross_sync/_mapping_meta.py
@@ -0,0 +1,64 @@
+# Copyright 2024 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.
+from __future__ import annotations
+from typing import Any
+
+
+class MappingMeta(type):
+ """
+ Metaclass to provide add_mapping functionality, allowing users to add
+ custom attributes to derived classes at runtime.
+
+ Using a metaclass allows us to share functionality between CrossSync
+ and CrossSync._Sync_Impl, and it works better with mypy checks than
+ monkypatching
+ """
+
+ # list of attributes that can be added to the derived class at runtime
+ _runtime_replacements: dict[tuple[MappingMeta, str], Any] = {}
+
+ def add_mapping(cls: MappingMeta, name: str, value: Any):
+ """
+ Add a new attribute to the class, for replacing library-level symbols
+
+ Raises:
+ - AttributeError if the attribute already exists with a different value
+ """
+ key = (cls, name)
+ old_value = cls._runtime_replacements.get(key)
+ if old_value is None:
+ cls._runtime_replacements[key] = value
+ elif old_value != value:
+ raise AttributeError(f"Conflicting assignments for CrossSync.{name}")
+
+ def add_mapping_decorator(cls: MappingMeta, name: str):
+ """
+ Exposes add_mapping as a class decorator
+ """
+
+ def decorator(wrapped_cls):
+ cls.add_mapping(name, wrapped_cls)
+ return wrapped_cls
+
+ return decorator
+
+ def __getattr__(cls: MappingMeta, name: str):
+ """
+ Retrieve custom attributes
+ """
+ key = (cls, name)
+ found = cls._runtime_replacements.get(key)
+ if found is not None:
+ return found
+ raise AttributeError(f"CrossSync has no attribute {name}")
diff --git a/google/cloud/bigtable/data/_cross_sync/cross_sync.py b/google/cloud/bigtable/data/_cross_sync/cross_sync.py
new file mode 100644
index 000000000..1f1ee111a
--- /dev/null
+++ b/google/cloud/bigtable/data/_cross_sync/cross_sync.py
@@ -0,0 +1,334 @@
+# Copyright 2024 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.
+#
+"""
+CrossSync provides a toolset for sharing logic between async and sync codebases, including:
+- A set of decorators for annotating async classes and functions
+ (@CrossSync.export_sync, @CrossSync.convert, @CrossSync.drop_method, ...)
+- A set of wrappers to wrap common objects and types that have corresponding async and sync implementations
+ (CrossSync.Queue, CrossSync.Condition, CrossSync.Future, ...)
+- A set of function implementations for common async operations that can be used in both async and sync codebases
+ (CrossSync.gather_partials, CrossSync.wait, CrossSync.condition_wait, ...)
+- CrossSync.rm_aio(), which is used to annotate regions of the code containing async keywords to strip
+
+A separate module will use CrossSync annotations to generate a corresponding sync
+class based on a decorated async class.
+
+Usage Example:
+```python
+@CrossSync.export_sync(path="path/to/sync_module.py")
+
+ @CrossSync.convert
+ async def async_func(self, arg: int) -> int:
+ await CrossSync.sleep(1)
+ return arg
+```
+"""
+
+from __future__ import annotations
+
+from typing import (
+ TypeVar,
+ Any,
+ Callable,
+ Coroutine,
+ Sequence,
+ Union,
+ AsyncIterable,
+ AsyncIterator,
+ AsyncGenerator,
+ TYPE_CHECKING,
+)
+import typing
+
+import asyncio
+import sys
+import concurrent.futures
+import google.api_core.retry as retries
+import queue
+import threading
+import time
+from ._decorators import (
+ ConvertClass,
+ Convert,
+ Drop,
+ Pytest,
+ PytestFixture,
+)
+from ._mapping_meta import MappingMeta
+
+if TYPE_CHECKING:
+ from typing_extensions import TypeAlias
+
+T = TypeVar("T")
+
+
+class CrossSync(metaclass=MappingMeta):
+ # support CrossSync.is_async to check if the current environment is async
+ is_async = True
+
+ # provide aliases for common async functions and types
+ sleep = asyncio.sleep
+ retry_target = retries.retry_target_async
+ retry_target_stream = retries.retry_target_stream_async
+ Retry = retries.AsyncRetry
+ Queue: TypeAlias = asyncio.Queue
+ Condition: TypeAlias = asyncio.Condition
+ Future: TypeAlias = asyncio.Future
+ Task: TypeAlias = asyncio.Task
+ Event: TypeAlias = asyncio.Event
+ Semaphore: TypeAlias = asyncio.Semaphore
+ StopIteration: TypeAlias = StopAsyncIteration
+ # provide aliases for common async type annotations
+ Awaitable: TypeAlias = typing.Awaitable
+ Iterable: TypeAlias = AsyncIterable
+ Iterator: TypeAlias = AsyncIterator
+ Generator: TypeAlias = AsyncGenerator
+
+ # decorators
+ convert_class = ConvertClass.decorator # decorate classes to convert
+ convert = Convert.decorator # decorate methods to convert from async to sync
+ drop = Drop.decorator # decorate methods to remove from sync version
+ pytest = Pytest.decorator # decorate test methods to run with pytest-asyncio
+ pytest_fixture = (
+ PytestFixture.decorator
+ ) # decorate test methods to run with pytest fixture
+
+ @classmethod
+ def next(cls, iterable):
+ return iterable.__anext__()
+
+ @classmethod
+ def Mock(cls, *args, **kwargs):
+ """
+ Alias for AsyncMock, importing at runtime to avoid hard dependency on mock
+ """
+ try:
+ from unittest.mock import AsyncMock # type: ignore
+ except ImportError: # pragma: NO COVER
+ from mock import AsyncMock # type: ignore
+ return AsyncMock(*args, **kwargs)
+
+ @staticmethod
+ async def gather_partials(
+ partial_list: Sequence[Callable[[], Awaitable[T]]],
+ return_exceptions: bool = False,
+ sync_executor: concurrent.futures.ThreadPoolExecutor | None = None,
+ ) -> list[T | BaseException]:
+ """
+ abstraction over asyncio.gather, but with a set of partial functions instead
+ of coroutines, to work with sync functions.
+ To use gather with a set of futures instead of partials, use CrpssSync.wait
+
+ In the async version, the partials are expected to return an awaitable object. Patials
+ are unpacked and awaited in the gather call.
+
+ Sync version implemented with threadpool executor
+
+ Returns:
+ - a list of results (or exceptions, if return_exceptions=True) in the same order as partial_list
+ """
+ if not partial_list:
+ return []
+ awaitable_list = [partial() for partial in partial_list]
+ return await asyncio.gather(
+ *awaitable_list, return_exceptions=return_exceptions
+ )
+
+ @staticmethod
+ async def wait(
+ futures: Sequence[CrossSync.Future[T]], timeout: float | None = None
+ ) -> tuple[set[CrossSync.Future[T]], set[CrossSync.Future[T]]]:
+ """
+ abstraction over asyncio.wait
+
+ Return:
+ - a tuple of (done, pending) sets of futures
+ """
+ if not futures:
+ return set(), set()
+ return await asyncio.wait(futures, timeout=timeout)
+
+ @staticmethod
+ async def event_wait(
+ event: CrossSync.Event,
+ timeout: float | None = None,
+ async_break_early: bool = True,
+ ) -> None:
+ """
+ abstraction over asyncio.Event.wait
+
+ Args:
+ - event: event to wait for
+ - timeout: if set, will break out early after `timeout` seconds
+ - async_break_early: if False, the async version will wait for
+ the full timeout even if the event is set before the timeout.
+ This avoids creating a new background task
+ """
+ if timeout is None:
+ await event.wait()
+ elif not async_break_early:
+ if not event.is_set():
+ await asyncio.sleep(timeout)
+ else:
+ try:
+ await asyncio.wait_for(event.wait(), timeout=timeout)
+ except asyncio.TimeoutError:
+ pass
+
+ @staticmethod
+ def create_task(
+ fn: Callable[..., Coroutine[Any, Any, T]],
+ *fn_args,
+ sync_executor: concurrent.futures.ThreadPoolExecutor | None = None,
+ task_name: str | None = None,
+ **fn_kwargs,
+ ) -> CrossSync.Task[T]:
+ """
+ abstraction over asyncio.create_task. Sync version implemented with threadpool executor
+
+ sync_executor: ThreadPoolExecutor to use for sync operations. Ignored in async version
+ """
+ task: CrossSync.Task[T] = asyncio.create_task(fn(*fn_args, **fn_kwargs))
+ if task_name and sys.version_info >= (3, 8):
+ task.set_name(task_name)
+ return task
+
+ @staticmethod
+ async def yield_to_event_loop() -> None:
+ """
+ Call asyncio.sleep(0) to yield to allow other tasks to run
+ """
+ await asyncio.sleep(0)
+
+ @staticmethod
+ def verify_async_event_loop() -> None:
+ """
+ Raises RuntimeError if the event loop is not running
+ """
+ asyncio.get_running_loop()
+
+ @staticmethod
+ def rm_aio(statement: T) -> T:
+ """
+ Used to annotate regions of the code containing async keywords to strip
+
+ All async keywords inside an rm_aio call are removed, along with
+ `async with` and `async for` statements containing CrossSync.rm_aio() in the body
+ """
+ return statement
+
+ class _Sync_Impl(metaclass=MappingMeta):
+ """
+ Provide sync versions of the async functions and types in CrossSync
+ """
+
+ is_async = False
+
+ sleep = time.sleep
+ next = next
+ retry_target = retries.retry_target
+ retry_target_stream = retries.retry_target_stream
+ Retry = retries.Retry
+ Queue: TypeAlias = queue.Queue
+ Condition: TypeAlias = threading.Condition
+ Future: TypeAlias = concurrent.futures.Future
+ Task: TypeAlias = concurrent.futures.Future
+ Event: TypeAlias = threading.Event
+ Semaphore: TypeAlias = threading.Semaphore
+ StopIteration: TypeAlias = StopIteration
+ # type annotations
+ Awaitable: TypeAlias = Union[T]
+ Iterable: TypeAlias = typing.Iterable
+ Iterator: TypeAlias = typing.Iterator
+ Generator: TypeAlias = typing.Generator
+
+ @classmethod
+ def Mock(cls, *args, **kwargs):
+ from unittest.mock import Mock
+
+ return Mock(*args, **kwargs)
+
+ @staticmethod
+ def event_wait(
+ event: CrossSync._Sync_Impl.Event,
+ timeout: float | None = None,
+ async_break_early: bool = True,
+ ) -> None:
+ event.wait(timeout=timeout)
+
+ @staticmethod
+ def gather_partials(
+ partial_list: Sequence[Callable[[], T]],
+ return_exceptions: bool = False,
+ sync_executor: concurrent.futures.ThreadPoolExecutor | None = None,
+ ) -> list[T | BaseException]:
+ if not partial_list:
+ return []
+ if not sync_executor:
+ raise ValueError("sync_executor is required for sync version")
+ futures_list = [sync_executor.submit(partial) for partial in partial_list]
+ results_list: list[T | BaseException] = []
+ for future in futures_list:
+ found_exc = future.exception()
+ if found_exc is not None:
+ if return_exceptions:
+ results_list.append(found_exc)
+ else:
+ raise found_exc
+ else:
+ results_list.append(future.result())
+ return results_list
+
+ @staticmethod
+ def wait(
+ futures: Sequence[CrossSync._Sync_Impl.Future[T]],
+ timeout: float | None = None,
+ ) -> tuple[
+ set[CrossSync._Sync_Impl.Future[T]], set[CrossSync._Sync_Impl.Future[T]]
+ ]:
+ if not futures:
+ return set(), set()
+ return concurrent.futures.wait(futures, timeout=timeout)
+
+ @staticmethod
+ def create_task(
+ fn: Callable[..., T],
+ *fn_args,
+ sync_executor: concurrent.futures.ThreadPoolExecutor | None = None,
+ task_name: str | None = None,
+ **fn_kwargs,
+ ) -> CrossSync._Sync_Impl.Task[T]:
+ """
+ abstraction over asyncio.create_task. Sync version implemented with threadpool executor
+
+ sync_executor: ThreadPoolExecutor to use for sync operations. Ignored in async version
+ """
+ if not sync_executor:
+ raise ValueError("sync_executor is required for sync version")
+ return sync_executor.submit(fn, *fn_args, **fn_kwargs)
+
+ @staticmethod
+ def yield_to_event_loop() -> None:
+ """
+ No-op for sync version
+ """
+ pass
+
+ @staticmethod
+ def verify_async_event_loop() -> None:
+ """
+ No-op for sync version
+ """
+ pass
diff --git a/google/cloud/bigtable/data/_helpers.py b/google/cloud/bigtable/data/_helpers.py
new file mode 100644
index 000000000..e848ebc6f
--- /dev/null
+++ b/google/cloud/bigtable/data/_helpers.py
@@ -0,0 +1,309 @@
+#
+# 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.
+#
+"""
+Helper functions used in various places in the library.
+"""
+from __future__ import annotations
+
+from typing import Sequence, List, Tuple, TYPE_CHECKING, Union
+import time
+import enum
+from collections import namedtuple
+from google.cloud.bigtable.data.read_rows_query import ReadRowsQuery
+
+from google.api_core import exceptions as core_exceptions
+from google.api_core.retry import exponential_sleep_generator
+from google.api_core.retry import RetryFailureReason
+from google.cloud.bigtable.data.exceptions import RetryExceptionGroup
+
+if TYPE_CHECKING:
+ import grpc
+ from google.cloud.bigtable.data._async.client import _DataApiTargetAsync
+ from google.cloud.bigtable.data._sync_autogen.client import _DataApiTarget
+
+"""
+Helper functions used in various places in the library.
+"""
+
+# Type alias for the output of sample_keys
+RowKeySamples = List[Tuple[bytes, int]]
+
+# type alias for the output of query.shard()
+ShardedQuery = List[ReadRowsQuery]
+
+# used by read_rows_sharded to limit how many requests are attempted in parallel
+_CONCURRENCY_LIMIT = 10
+
+# used to identify an active bigtable resource that needs to be warmed through PingAndWarm
+# each instance/app_profile_id pair needs to be individually tracked
+_WarmedInstanceKey = namedtuple(
+ "_WarmedInstanceKey", ["instance_name", "app_profile_id"]
+)
+
+
+# enum used on method calls when table defaults should be used
+class TABLE_DEFAULT(enum.Enum):
+ # default for mutate_row, sample_row_keys, check_and_mutate_row, and read_modify_write_row
+ DEFAULT = "DEFAULT"
+ # default for read_rows, read_rows_stream, read_rows_sharded, row_exists, and read_row
+ READ_ROWS = "READ_ROWS_DEFAULT"
+ # default for bulk_mutate_rows and mutations_batcher
+ MUTATE_ROWS = "MUTATE_ROWS_DEFAULT"
+
+
+def _attempt_timeout_generator(
+ per_request_timeout: float | None, operation_timeout: float
+):
+ """
+ Generator that yields the timeout value for each attempt of a retry loop.
+
+ Will return per_request_timeout until the operation_timeout is approached,
+ at which point it will return the remaining time in the operation_timeout.
+
+ Args:
+ per_request_timeout: The timeout value to use for each request, in seconds.
+ If None, the operation_timeout will be used for each request.
+ operation_timeout: The timeout value to use for the entire operationm in seconds.
+ Yields:
+ float: The timeout value to use for the next request, in seonds
+ """
+ per_request_timeout = (
+ per_request_timeout if per_request_timeout is not None else operation_timeout
+ )
+ deadline = operation_timeout + time.monotonic()
+ while True:
+ yield max(0, min(per_request_timeout, deadline - time.monotonic()))
+
+
+def _retry_exception_factory(
+ exc_list: list[Exception],
+ reason: RetryFailureReason,
+ timeout_val: float | None,
+) -> tuple[Exception, Exception | None]:
+ """
+ Build retry error based on exceptions encountered during operation
+
+ Args:
+ exc_list: list of exceptions encountered during operation
+ is_timeout: whether the operation failed due to timeout
+ timeout_val: the operation timeout value in seconds, for constructing
+ the error message
+ Returns:
+ tuple[Exception, Exception|None]:
+ tuple of the exception to raise, and a cause exception if applicable
+ """
+ if reason == RetryFailureReason.TIMEOUT:
+ timeout_val_str = f"of {timeout_val:0.1f}s " if timeout_val is not None else ""
+ # if failed due to timeout, raise deadline exceeded as primary exception
+ source_exc: Exception = core_exceptions.DeadlineExceeded(
+ f"operation_timeout{timeout_val_str} exceeded"
+ )
+ elif exc_list:
+ # otherwise, raise non-retryable error as primary exception
+ source_exc = exc_list.pop()
+ else:
+ source_exc = RuntimeError("failed with unspecified exception")
+ # use the retry exception group as the cause of the exception
+ cause_exc: Exception | None = RetryExceptionGroup(exc_list) if exc_list else None
+ source_exc.__cause__ = cause_exc
+ return source_exc, cause_exc
+
+
+def _get_timeouts(
+ operation: float | TABLE_DEFAULT,
+ attempt: float | None | TABLE_DEFAULT,
+ table: "_DataApiTargetAsync" | "_DataApiTarget",
+) -> tuple[float, float]:
+ """
+ Convert passed in timeout values to floats, using table defaults if necessary.
+
+ attempt will use operation value if None, or if larger than operation.
+
+ Will call _validate_timeouts on the outputs, and raise ValueError if the
+ resulting timeouts are invalid.
+
+ Args:
+ operation: The timeout value to use for the entire operation, in seconds.
+ attempt: The timeout value to use for each attempt, in seconds.
+ table: The table to use for default values.
+ Returns:
+ tuple[float, float]: A tuple of (operation_timeout, attempt_timeout)
+ """
+ # load table defaults if necessary
+ if operation == TABLE_DEFAULT.DEFAULT:
+ final_operation = table.default_operation_timeout
+ elif operation == TABLE_DEFAULT.READ_ROWS:
+ final_operation = table.default_read_rows_operation_timeout
+ elif operation == TABLE_DEFAULT.MUTATE_ROWS:
+ final_operation = table.default_mutate_rows_operation_timeout
+ else:
+ final_operation = operation
+ if attempt == TABLE_DEFAULT.DEFAULT:
+ attempt = table.default_attempt_timeout
+ elif attempt == TABLE_DEFAULT.READ_ROWS:
+ attempt = table.default_read_rows_attempt_timeout
+ elif attempt == TABLE_DEFAULT.MUTATE_ROWS:
+ attempt = table.default_mutate_rows_attempt_timeout
+
+ return _align_timeouts(final_operation, attempt)
+
+
+def _align_timeouts(operation: float, attempt: float | None) -> tuple[float, float]:
+ """
+ Convert passed in timeout values to floats.
+
+ attempt will use operation value if None, or if larger than operation.
+
+ Will call _validate_timeouts on the outputs, and raise ValueError if the
+ resulting timeouts are invalid.
+
+ Args:
+ operation: The timeout value to use for the entire operation, in seconds.
+ attempt: The timeout value to use for each attempt, in seconds.
+ Returns:
+ tuple[float, float]: A tuple of (operation_timeout, attempt_timeout)
+ """
+ if attempt is None:
+ # no timeout specified, use operation timeout for both
+ final_attempt = operation
+ else:
+ # cap attempt timeout at operation timeout
+ final_attempt = min(attempt, operation) if operation else attempt
+
+ _validate_timeouts(operation, final_attempt, allow_none=False)
+ return operation, final_attempt
+
+
+def _validate_timeouts(
+ operation_timeout: float, attempt_timeout: float | None, allow_none: bool = False
+):
+ """
+ Helper function that will verify that timeout values are valid, and raise
+ an exception if they are not.
+
+ Args:
+ operation_timeout: The timeout value to use for the entire operation, in seconds.
+ attempt_timeout: The timeout value to use for each attempt, in seconds.
+ allow_none: If True, attempt_timeout can be None. If False, None values will raise an exception.
+ Raises:
+ ValueError: if operation_timeout or attempt_timeout are invalid.
+ """
+ if operation_timeout is None:
+ raise ValueError("operation_timeout cannot be None")
+ if operation_timeout <= 0:
+ raise ValueError("operation_timeout must be greater than 0")
+ if not allow_none and attempt_timeout is None:
+ raise ValueError("attempt_timeout must not be None")
+ elif attempt_timeout is not None:
+ if attempt_timeout <= 0:
+ raise ValueError("attempt_timeout must be greater than 0")
+
+
+def _get_error_type(
+ call_code: Union["grpc.StatusCode", int, type[Exception]]
+) -> type[Exception]:
+ """Helper function for ensuring the object is an exception type.
+ If it is not, the proper GoogleAPICallError type is infered from the status
+ code.
+
+ Args:
+ - call_code: Exception type or gRPC status code.
+ """
+ if isinstance(call_code, type):
+ return call_code
+ else:
+ return type(core_exceptions.from_grpc_status(call_code, ""))
+
+
+def _get_retryable_errors(
+ call_codes: Sequence["grpc.StatusCode" | int | type[Exception]] | TABLE_DEFAULT,
+ table: "_DataApiTargetAsync" | "_DataApiTarget",
+) -> list[type[Exception]]:
+ """
+ Convert passed in retryable error codes to a list of exception types.
+
+ Args:
+ call_codes: The error codes to convert. Can be a list of grpc.StatusCode values,
+ int values, or Exception types, or a TABLE_DEFAULT value.
+ table: The table to use for default values.
+ Returns:
+ list[type[Exception]]: A list of exception types to retry on.
+ """
+ # load table defaults if necessary
+ if call_codes == TABLE_DEFAULT.DEFAULT:
+ call_codes = table.default_retryable_errors
+ elif call_codes == TABLE_DEFAULT.READ_ROWS:
+ call_codes = table.default_read_rows_retryable_errors
+ elif call_codes == TABLE_DEFAULT.MUTATE_ROWS:
+ call_codes = table.default_mutate_rows_retryable_errors
+
+ return [_get_error_type(e) for e in call_codes]
+
+
+class TrackedBackoffGenerator:
+ """
+ Generator class for exponential backoff sleep times.
+ This implementation builds on top of api_core.retries.exponential_sleep_generator,
+ adding the ability to retrieve previous values using get_attempt_backoff(idx).
+ This is used by the Metrics class to track the sleep times used for each attempt.
+ """
+
+ def __init__(self, initial=0.01, maximum=60, multiplier=2):
+ self.history = []
+ self.subgenerator = exponential_sleep_generator(
+ initial=initial, maximum=maximum, multiplier=multiplier
+ )
+ self._next_override: float | None = None
+
+ def __iter__(self):
+ return self
+
+ def set_next(self, next_value: float):
+ """
+ Set the next backoff value, instead of generating one from subgenerator.
+ After the value is yielded, it will go back to using self.subgenerator.
+
+ If set_next is called twice before the next() is called, only the latest
+ value will be used and others discarded
+
+ Args:
+ next_value: the upcomming value to yield when next() is called
+ Raises:
+ ValueError: if next_value is negative
+ """
+ if next_value < 0:
+ raise ValueError("backoff value cannot be less than 0")
+ self._next_override = next_value
+
+ def __next__(self) -> float:
+ if self._next_override is not None:
+ next_backoff = self._next_override
+ self._next_override = None
+ else:
+ next_backoff = next(self.subgenerator)
+ self.history.append(next_backoff)
+ return next_backoff
+
+ def get_attempt_backoff(self, attempt_idx) -> float:
+ """
+ returns the backoff time for a specific attempt index, starting at 0.
+
+ Args:
+ attempt_idx: the index of the attempt to return backoff for
+ Raises:
+ IndexError: if attempt_idx is negative, or not in history
+ """
+ if attempt_idx < 0:
+ raise IndexError("received negative attempt number")
+ return self.history[attempt_idx]
diff --git a/google/cloud/bigtable/data/_metrics/__init__.py b/google/cloud/bigtable/data/_metrics/__init__.py
new file mode 100644
index 000000000..26cfc1326
--- /dev/null
+++ b/google/cloud/bigtable/data/_metrics/__init__.py
@@ -0,0 +1,35 @@
+# Copyright 2023 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.
+from google.cloud.bigtable.data._metrics.metrics_controller import (
+ BigtableClientSideMetricsController,
+)
+
+from google.cloud.bigtable.data._metrics.data_model import ActiveOperationMetric
+from google.cloud.bigtable.data._metrics.data_model import ActiveAttemptMetric
+from google.cloud.bigtable.data._metrics.data_model import CompletedOperationMetric
+from google.cloud.bigtable.data._metrics.data_model import CompletedAttemptMetric
+from google.cloud.bigtable.data._metrics.data_model import OperationState
+from google.cloud.bigtable.data._metrics.data_model import OperationType
+from google.cloud.bigtable.data._metrics.tracked_retry import tracked_retry
+
+__all__ = (
+ "BigtableClientSideMetricsController",
+ "OperationType",
+ "OperationState",
+ "ActiveOperationMetric",
+ "ActiveAttemptMetric",
+ "CompletedOperationMetric",
+ "CompletedAttemptMetric",
+ "tracked_retry",
+)
diff --git a/google/cloud/bigtable/data/_metrics/data_model.py b/google/cloud/bigtable/data/_metrics/data_model.py
new file mode 100644
index 000000000..64dd63bfa
--- /dev/null
+++ b/google/cloud/bigtable/data/_metrics/data_model.py
@@ -0,0 +1,469 @@
+# Copyright 2023 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.
+from __future__ import annotations
+
+from typing import ClassVar, Tuple, cast, TYPE_CHECKING
+
+import time
+import re
+import logging
+import contextvars
+
+from enum import Enum
+from functools import lru_cache
+from dataclasses import dataclass
+from dataclasses import field
+from grpc import StatusCode
+from grpc import RpcError
+from grpc.aio import AioRpcError
+
+import google.cloud.bigtable.data.exceptions as bt_exceptions
+from google.cloud.bigtable_v2.types.response_params import ResponseParams
+from google.cloud.bigtable.data._helpers import TrackedBackoffGenerator
+from google.protobuf.message import DecodeError
+
+if TYPE_CHECKING:
+ from google.cloud.bigtable.data._metrics.handlers._base import MetricsHandler
+
+
+LOGGER = logging.getLogger(__name__)
+
+# default values for zone and cluster data, if not captured
+DEFAULT_ZONE = "global"
+DEFAULT_CLUSTER_ID = ""
+
+# keys for parsing metadata blobs
+BIGTABLE_LOCATION_METADATA_KEY = "x-goog-ext-425905942-bin"
+SERVER_TIMING_METADATA_KEY = "server-timing"
+SERVER_TIMING_REGEX = re.compile(r".*gfet4t7;\s*dur=(\d+\.?\d*).*")
+
+INVALID_STATE_ERROR = "Invalid state for {}: {}"
+
+
+class OperationType(Enum):
+ """Enum for the type of operation being performed."""
+
+ READ_ROWS = "ReadRows"
+ SAMPLE_ROW_KEYS = "SampleRowKeys"
+ BULK_MUTATE_ROWS = "MutateRows"
+ MUTATE_ROW = "MutateRow"
+ CHECK_AND_MUTATE = "CheckAndMutateRow"
+ READ_MODIFY_WRITE = "ReadModifyWriteRow"
+
+
+class OperationState(Enum):
+ """Enum for the state of the active operation.
+
+ âââââââââââââ
+ â CREATED ââââââââââ
+ âââââââŹââââââ â
+ â â
+ ⌠â
+ ââ¶ ACTIVE_ATTEMPT âââââ
+ â â ââ
+ â ⌠ââ
+ ââ BETWEEN_ATTEMPTS ââ
+ â ââ
+ ⌠ââ
+ âââââââââââââ ââ
+ â COMPLETED â ââââââââ
+ âââââââââââââ ââââââââ
+ """
+
+ CREATED = 0
+ ACTIVE_ATTEMPT = 1
+ BETWEEN_ATTEMPTS = 2
+ COMPLETED = 3
+
+
+@dataclass(frozen=True)
+class CompletedAttemptMetric:
+ """
+ An immutable dataclass representing the data associated with a
+ completed rpc attempt.
+
+ Operation-level fields (eg. type, cluster, zone) are stored on the
+ corresponding CompletedOperationMetric or ActiveOperationMetric object.
+ """
+
+ duration_ns: int
+ end_status: StatusCode
+ gfe_latency_ns: int | None = None
+ application_blocking_time_ns: int = 0
+ backoff_before_attempt_ns: int = 0
+
+
+@dataclass(frozen=True)
+class CompletedOperationMetric:
+ """
+ An immutable dataclass representing the data associated with a
+ completed rpc operation.
+
+ Attempt-level fields (eg. duration, latencies, etc) are stored on the
+ corresponding CompletedAttemptMetric object.
+ """
+
+ op_type: OperationType
+ duration_ns: int
+ completed_attempts: list[CompletedAttemptMetric]
+ final_status: StatusCode
+ cluster_id: str
+ zone: str
+ is_streaming: bool
+ first_response_latency_ns: int | None = None
+ flow_throttling_time_ns: int = 0
+
+
+@dataclass
+class ActiveAttemptMetric:
+ """
+ A dataclass representing the data associated with an rpc attempt that is
+ currently in progress. Fields are mutable and may be optional.
+ """
+
+ # keep monotonic timestamps for active attempts
+ start_time_ns: int = field(default_factory=lambda: time.monotonic_ns())
+ # the time taken by the backend, in nanoseconds. Taken from response header
+ gfe_latency_ns: int | None = None
+ # time waiting on user to process the response, in nanoseconds
+ # currently only relevant for ReadRows
+ application_blocking_time_ns: int = 0
+ # backoff time is added to application_blocking_time_ns
+ backoff_before_attempt_ns: int = 0
+
+
+@dataclass
+class ActiveOperationMetric:
+ """
+ A dataclass representing the data associated with an rpc operation that is
+ currently in progress. Fields are mutable and may be optional.
+ """
+
+ op_type: OperationType
+ state: OperationState = OperationState.CREATED
+ # create a default backoff generator, initialized with standard default backoff values
+ backoff_generator: TrackedBackoffGenerator = field(
+ default_factory=lambda: TrackedBackoffGenerator(
+ initial=0.01, maximum=60, multiplier=2
+ )
+ )
+ # keep monotonic timestamps for active operations
+ start_time_ns: int = field(default_factory=lambda: time.monotonic_ns())
+ active_attempt: ActiveAttemptMetric | None = None
+ cluster_id: str | None = None
+ zone: str | None = None
+ completed_attempts: list[CompletedAttemptMetric] = field(default_factory=list)
+ is_streaming: bool = False # only True for read_rows operations
+ handlers: list[MetricsHandler] = field(default_factory=list)
+ # the time it takes to recieve the first response from the server, in nanoseconds
+ # attached by interceptor
+ # currently only tracked for ReadRows
+ first_response_latency_ns: int | None = None
+ # time waiting on flow control, in nanoseconds
+ flow_throttling_time_ns: int = 0
+
+ _active_operation_context: ClassVar[
+ contextvars.ContextVar[ActiveOperationMetric]
+ ] = contextvars.ContextVar("active_operation_context")
+
+ @classmethod
+ def from_context(cls) -> ActiveOperationMetric | None:
+ """Retrieves the active operation from the current execution context.
+
+ Because execution within a context is sequential, this guarantees
+ retrieval of the single, unique operation, isolated from other
+ concurrent RPCs.
+
+ Note:
+ This is intended to be called by gRPC interceptors at the start
+ of an RPC.
+
+ Returns:
+ ActiveOperationMetric: The current active operation.
+ None: If no operation is set, or if the current operation is
+ already in the `COMPLETED` state.
+ """
+ op = cls._active_operation_context.get(None)
+ if op and op.state == OperationState.COMPLETED:
+ return None
+ return op
+
+ def __post_init__(self):
+ """
+ Save new instances to contextvars on init
+ """
+ self._active_operation_context.set(self)
+
+ def start(self) -> None:
+ """
+ Optionally called to mark the start of the operation. If not called,
+ the operation will be started at initialization.
+
+ StartState: CREATED
+ EndState: CREATED
+ """
+ if self.state != OperationState.CREATED:
+ return self._handle_error(INVALID_STATE_ERROR.format("start", self.state))
+ self.start_time_ns = time.monotonic_ns()
+ # set as active operation in contextvars
+ self._active_operation_context.set(self)
+
+ def start_attempt(self) -> ActiveAttemptMetric | None:
+ """
+ Called to initiate a new attempt for the operation.
+
+ StartState: CREATED | BETWEEN_ATTEMPTS
+ EndState: ACTIVE_ATTEMPT
+ """
+ if (
+ self.state != OperationState.BETWEEN_ATTEMPTS
+ and self.state != OperationState.CREATED
+ ):
+ return self._handle_error(
+ INVALID_STATE_ERROR.format("start_attempt", self.state)
+ )
+ # set as active operation in contextvars
+ self._active_operation_context.set(self)
+
+ try:
+ # find backoff value before this attempt
+ prev_attempt_idx = len(self.completed_attempts) - 1
+ backoff = self.backoff_generator.get_attempt_backoff(prev_attempt_idx)
+ # generator will return the backoff time in seconds, so convert to nanoseconds
+ backoff_ns = int(backoff * 1e9)
+ except IndexError:
+ # backoff value not found
+ backoff_ns = 0
+
+ self.active_attempt = ActiveAttemptMetric(backoff_before_attempt_ns=backoff_ns)
+ self.state = OperationState.ACTIVE_ATTEMPT
+ return self.active_attempt
+
+ def add_response_metadata(self, metadata: dict[str, bytes | str]) -> None:
+ """
+ Attach trailing metadata to the active attempt.
+
+ If not called, default values for the metadata will be used.
+
+ StartState: ACTIVE_ATTEMPT
+ EndState: ACTIVE_ATTEMPT
+
+ Args:
+ - metadata: the metadata as extracted from the grpc call
+ """
+ if self.state != OperationState.ACTIVE_ATTEMPT:
+ return self._handle_error(
+ INVALID_STATE_ERROR.format("add_response_metadata", self.state)
+ )
+ if self.cluster_id is None or self.zone is None:
+ # BIGTABLE_LOCATION_METADATA_KEY should give a binary-encoded ResponseParams proto
+ blob = cast(bytes, metadata.get(BIGTABLE_LOCATION_METADATA_KEY))
+ if blob:
+ parse_result = self._parse_response_metadata_blob(blob)
+ if parse_result is not None:
+ cluster, zone = parse_result
+ if cluster:
+ self.cluster_id = cluster
+ if zone:
+ self.zone = zone
+ else:
+ self._handle_error(
+ f"Failed to decode {BIGTABLE_LOCATION_METADATA_KEY} metadata: {blob!r}"
+ )
+ # SERVER_TIMING_METADATA_KEY should give a string with the server-latency headers
+ timing_header = cast(str, metadata.get(SERVER_TIMING_METADATA_KEY))
+ if timing_header:
+ timing_data = SERVER_TIMING_REGEX.match(timing_header)
+ if timing_data and self.active_attempt:
+ gfe_latency_ms = float(timing_data.group(1))
+ self.active_attempt.gfe_latency_ns = int(gfe_latency_ms * 1e6)
+
+ @staticmethod
+ @lru_cache(maxsize=32)
+ def _parse_response_metadata_blob(blob: bytes) -> Tuple[str, str] | None:
+ """
+ Parse the response metadata blob and return a tuple of cluster and zone.
+
+ Function is cached to avoid parsing the same blob multiple times.
+
+ Args:
+ - blob: the metadata blob as extracted from the grpc call
+ Returns:
+ - a tuple of cluster_id and zone, or None if parsing failed
+ """
+ try:
+ proto = ResponseParams.pb().FromString(blob)
+ return proto.cluster_id, proto.zone_id
+ except (DecodeError, TypeError):
+ # failed to parse metadata
+ return None
+
+ def end_attempt_with_status(self, status: StatusCode | BaseException) -> None:
+ """
+ Called to mark the end of an attempt for the operation.
+
+ Typically, this is used to mark a retryable error. If a retry will not
+ be attempted, `end_with_status` or `end_with_success` should be used
+ to finalize the operation along with the attempt.
+
+ StartState: ACTIVE_ATTEMPT
+ EndState: BETWEEN_ATTEMPTS
+
+ Args:
+ - status: The status of the attempt.
+ """
+ if self.state != OperationState.ACTIVE_ATTEMPT or self.active_attempt is None:
+ return self._handle_error(
+ INVALID_STATE_ERROR.format("end_attempt_with_status", self.state)
+ )
+ if isinstance(status, BaseException):
+ status = self._exc_to_status(status)
+ duration_ns = self._ensure_positive(
+ time.monotonic_ns() - self.active_attempt.start_time_ns, "duration"
+ )
+ complete_attempt = CompletedAttemptMetric(
+ duration_ns=duration_ns,
+ end_status=status,
+ gfe_latency_ns=self.active_attempt.gfe_latency_ns,
+ application_blocking_time_ns=self.active_attempt.application_blocking_time_ns,
+ backoff_before_attempt_ns=self.active_attempt.backoff_before_attempt_ns,
+ )
+ self.completed_attempts.append(complete_attempt)
+ self.active_attempt = None
+ self.state = OperationState.BETWEEN_ATTEMPTS
+ for handler in self.handlers:
+ handler.on_attempt_complete(complete_attempt, self)
+
+ def end_with_status(self, status: StatusCode | BaseException) -> None:
+ """
+ Called to mark the end of the operation. If there is an active attempt,
+ end_attempt_with_status will be called with the same status.
+
+ StartState: CREATED | ACTIVE_ATTEMPT | BETWEEN_ATTEMPTS
+ EndState: COMPLETED
+
+ Causes on_operation_completed to be called for each registered handler.
+
+ Args:
+ - status: The status of the operation.
+ """
+ if self.state == OperationState.COMPLETED:
+ return self._handle_error(
+ INVALID_STATE_ERROR.format("end_with_status", self.state)
+ )
+ final_status = (
+ self._exc_to_status(status) if isinstance(status, BaseException) else status
+ )
+ if self.state == OperationState.ACTIVE_ATTEMPT:
+ self.end_attempt_with_status(final_status)
+ duration_ns = self._ensure_positive(
+ time.monotonic_ns() - self.start_time_ns, "duration"
+ )
+ finalized = CompletedOperationMetric(
+ op_type=self.op_type,
+ completed_attempts=self.completed_attempts,
+ duration_ns=duration_ns,
+ final_status=final_status,
+ cluster_id=self.cluster_id or DEFAULT_CLUSTER_ID,
+ zone=self.zone or DEFAULT_ZONE,
+ is_streaming=self.is_streaming,
+ first_response_latency_ns=self.first_response_latency_ns,
+ flow_throttling_time_ns=self.flow_throttling_time_ns,
+ )
+ self.state = OperationState.COMPLETED
+ for handler in self.handlers:
+ handler.on_operation_complete(finalized)
+
+ def end_with_success(self):
+ """
+ Called to mark the end of the operation with a successful status.
+
+ StartState: CREATED | ACTIVE_ATTEMPT | BETWEEN_ATTEMPTS
+ EndState: COMPLETED
+
+ Causes on_operation_completed to be called for each registered handler.
+ """
+ return self.end_with_status(StatusCode.OK)
+
+ @staticmethod
+ def _exc_to_status(exc: BaseException) -> StatusCode:
+ """
+ Extracts the grpc status code from an exception.
+
+ Exception groups and wrappers will be parsed to find the underlying
+ grpc Exception.
+
+ If the exception is not a grpc exception, will return StatusCode.UNKNOWN.
+
+ Args:
+ - exc: The exception to extract the status code from.
+ """
+ if isinstance(exc, bt_exceptions._BigtableExceptionGroup):
+ exc = exc.exceptions[-1]
+ if hasattr(exc, "grpc_status_code") and exc.grpc_status_code is not None:
+ return exc.grpc_status_code
+ if (
+ exc.__cause__
+ and hasattr(exc.__cause__, "grpc_status_code")
+ and exc.__cause__.grpc_status_code is not None
+ ):
+ return exc.__cause__.grpc_status_code
+ if isinstance(exc, AioRpcError) or isinstance(exc, RpcError):
+ return exc.code()
+ return StatusCode.UNKNOWN
+
+ @staticmethod
+ def _handle_error(message: str) -> None:
+ """
+ log error metric system error messages
+
+ Args:
+ - message: The message to include in the exception or warning.
+ """
+ full_message = f"Error in Bigtable Metrics: {message}"
+ LOGGER.warning(full_message)
+
+ def _ensure_positive(self, value: int, field_name: str) -> int:
+ """
+ Helper to replace negative value with 0, and record an error
+ """
+ if value < 0:
+ self._handle_error(f"received negative value for {field_name}: {value}")
+ return 0
+ return value
+
+ def __enter__(self):
+ """
+ Implements the async manager protocol
+
+ Using the operation's context manager provides assurances that the operation
+ is always closed when complete, with the proper status code automaticallty
+ detected when an exception is raised.
+ """
+ return self
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ """
+ Implements the context manager protocol
+
+ The operation is automatically ended on exit, with the status determined
+ by the exception type and value.
+
+ If operation was already ended manually, do nothing.
+ """
+ if not self.state == OperationState.COMPLETED:
+ if exc_val is None:
+ self.end_with_success()
+ else:
+ self.end_with_status(exc_val)
diff --git a/google/cloud/bigtable/data/_metrics/handlers/_base.py b/google/cloud/bigtable/data/_metrics/handlers/_base.py
new file mode 100644
index 000000000..884091fdd
--- /dev/null
+++ b/google/cloud/bigtable/data/_metrics/handlers/_base.py
@@ -0,0 +1,38 @@
+# Copyright 2023 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.
+from google.cloud.bigtable.data._metrics.data_model import ActiveOperationMetric
+from google.cloud.bigtable.data._metrics.data_model import CompletedAttemptMetric
+from google.cloud.bigtable.data._metrics.data_model import CompletedOperationMetric
+
+
+class MetricsHandler:
+ """
+ Base class for all metrics handlers. Metrics handlers will receive callbacks
+ when operations and attempts are completed, and can use this information to
+ update some external metrics system.
+ """
+
+ def __init__(self, **kwargs):
+ pass
+
+ def on_operation_complete(self, op: CompletedOperationMetric) -> None:
+ pass
+
+ def on_attempt_complete(
+ self, attempt: CompletedAttemptMetric, op: ActiveOperationMetric
+ ) -> None:
+ pass
+
+ def close(self):
+ pass
diff --git a/google/cloud/bigtable/data/_metrics/metrics_controller.py b/google/cloud/bigtable/data/_metrics/metrics_controller.py
new file mode 100644
index 000000000..e9815f201
--- /dev/null
+++ b/google/cloud/bigtable/data/_metrics/metrics_controller.py
@@ -0,0 +1,63 @@
+# Copyright 2023 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.
+from __future__ import annotations
+
+from google.cloud.bigtable.data._metrics.data_model import ActiveOperationMetric
+from google.cloud.bigtable.data._metrics.handlers._base import MetricsHandler
+from google.cloud.bigtable.data._metrics.data_model import OperationType
+
+
+class BigtableClientSideMetricsController:
+ """
+ BigtableClientSideMetricsController is responsible for managing the
+ lifecycle of the metrics system. The Bigtable client library will
+ use this class to create new operations. Each operation will be
+ registered with the handlers associated with this controller.
+ """
+
+ def __init__(
+ self,
+ handlers: list[MetricsHandler] | None = None,
+ ):
+ """
+ Initializes the metrics controller.
+
+ Args:
+ - handlers: A list of MetricsHandler objects to subscribe to metrics events.
+ """
+ self.handlers: list[MetricsHandler] = handlers or []
+
+ def add_handler(self, handler: MetricsHandler) -> None:
+ """
+ Add a new handler to the list of handlers.
+
+ Args:
+ - handler: A MetricsHandler object to add to the list of subscribed handlers.
+ """
+ self.handlers.append(handler)
+
+ def create_operation(
+ self, op_type: OperationType, **kwargs
+ ) -> ActiveOperationMetric:
+ """
+ Creates a new operation and registers it with the subscribed handlers.
+ """
+ return ActiveOperationMetric(op_type, **kwargs, handlers=self.handlers)
+
+ def close(self):
+ """
+ Close all handlers.
+ """
+ for handler in self.handlers:
+ handler.close()
diff --git a/google/cloud/bigtable/data/_metrics/tracked_retry.py b/google/cloud/bigtable/data/_metrics/tracked_retry.py
new file mode 100644
index 000000000..94d2e5dcb
--- /dev/null
+++ b/google/cloud/bigtable/data/_metrics/tracked_retry.py
@@ -0,0 +1,133 @@
+# Copyright 2025 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.
+"""
+Methods for instrumenting an google.api_core.retry.retry_target or
+google.api_core.retry.retry_target_stream method
+
+`tracked_retry` will intercept `on_error` and `exception_factory`
+methods to update the associated ActiveOperationMetric when exceptions
+are encountered through the retryable rpc.
+"""
+from __future__ import annotations
+
+from typing import Callable, List, Optional, Tuple, TypeVar
+
+from grpc import StatusCode
+from google.api_core.exceptions import GoogleAPICallError
+from google.api_core.retry import RetryFailureReason
+from google.cloud.bigtable.data.exceptions import _MutateRowsIncomplete
+from google.cloud.bigtable.data._helpers import _retry_exception_factory
+from google.cloud.bigtable.data._metrics import ActiveOperationMetric
+from google.cloud.bigtable.data._metrics import OperationState
+
+
+T = TypeVar("T")
+
+
+ExceptionFactoryType = Callable[
+ [List[Exception], RetryFailureReason, Optional[float]],
+ Tuple[Exception, Optional[Exception]],
+]
+
+
+def _track_retryable_error(
+ operation: ActiveOperationMetric,
+) -> Callable[[Exception], None]:
+ """
+ Used as input to api_core.Retry classes, to track when retryable errors are encountered
+
+ Should be passed as on_error callback
+ """
+
+ def wrapper(exc: Exception) -> None:
+ try:
+ # record metadata from failed rpc
+ if isinstance(exc, GoogleAPICallError) and exc.errors:
+ rpc_error = exc.errors[-1]
+ metadata = list(rpc_error.trailing_metadata()) + list(
+ rpc_error.initial_metadata()
+ )
+ operation.add_response_metadata({k: v for k, v in metadata})
+ except Exception:
+ # ignore errors in metadata collection
+ pass
+ if isinstance(exc, _MutateRowsIncomplete):
+ # _MutateRowsIncomplete represents a successful rpc with some failed mutations
+ # mark the attempt as successful
+ operation.end_attempt_with_status(StatusCode.OK)
+ else:
+ operation.end_attempt_with_status(exc)
+
+ return wrapper
+
+
+def _track_terminal_error(
+ operation: ActiveOperationMetric, exception_factory: ExceptionFactoryType
+) -> ExceptionFactoryType:
+ """
+ Used as input to api_core.Retry classes, to track when terminal errors are encountered
+
+ Should be used as a wrapper over an exception_factory callback
+ """
+
+ def wrapper(
+ exc_list: List[Exception],
+ reason: RetryFailureReason,
+ timeout_val: float | None,
+ ) -> tuple[Exception, Exception | None]:
+ source_exc, cause_exc = exception_factory(exc_list, reason, timeout_val)
+ try:
+ # record metadata from failed rpc
+ if isinstance(source_exc, GoogleAPICallError) and source_exc.errors:
+ rpc_error = source_exc.errors[-1]
+ metadata = list(rpc_error.trailing_metadata()) + list(
+ rpc_error.initial_metadata()
+ )
+ operation.add_response_metadata({k: v for k, v in metadata})
+ except Exception:
+ # ignore errors in metadata collection
+ pass
+ if (
+ reason == RetryFailureReason.TIMEOUT
+ and operation.state == OperationState.ACTIVE_ATTEMPT
+ and exc_list
+ ):
+ # record ending attempt for timeout failures
+ attempt_exc = exc_list[-1]
+ _track_retryable_error(operation)(attempt_exc)
+ operation.end_with_status(source_exc)
+ return source_exc, cause_exc
+
+ return wrapper
+
+
+def tracked_retry(
+ *,
+ retry_fn: Callable[..., T],
+ operation: ActiveOperationMetric,
+ **kwargs,
+) -> T:
+ """
+ Wrapper for retry_rarget or retry_target_stream, which injects methods to
+ track the lifecycle of the retry using the provided ActiveOperationMetric
+ """
+ in_exception_factory = kwargs.pop("exception_factory", _retry_exception_factory)
+ kwargs.pop("on_error", None)
+ kwargs.pop("sleep_generator", None)
+ return retry_fn(
+ sleep_generator=operation.backoff_generator,
+ on_error=_track_retryable_error(operation),
+ exception_factory=_track_terminal_error(operation, in_exception_factory),
+ **kwargs,
+ )
diff --git a/google/cloud/bigtable/data/_sync_autogen/_mutate_rows.py b/google/cloud/bigtable/data/_sync_autogen/_mutate_rows.py
new file mode 100644
index 000000000..3bf7b562f
--- /dev/null
+++ b/google/cloud/bigtable/data/_sync_autogen/_mutate_rows.py
@@ -0,0 +1,184 @@
+# Copyright 2024 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.
+#
+
+# This file is automatically generated by CrossSync. Do not edit manually.
+
+from __future__ import annotations
+from typing import Sequence, TYPE_CHECKING
+from google.api_core import exceptions as core_exceptions
+from google.api_core import retry as retries
+import google.cloud.bigtable_v2.types.bigtable as types_pb
+import google.cloud.bigtable.data.exceptions as bt_exceptions
+from google.cloud.bigtable.data._helpers import _attempt_timeout_generator
+from google.cloud.bigtable.data._helpers import _retry_exception_factory
+from google.cloud.bigtable.data.mutations import _MUTATE_ROWS_REQUEST_MUTATION_LIMIT
+from google.cloud.bigtable.data.mutations import _EntryWithProto
+from google.cloud.bigtable.data._cross_sync import CrossSync
+
+if TYPE_CHECKING:
+ from google.cloud.bigtable.data.mutations import RowMutationEntry
+ from google.cloud.bigtable_v2.services.bigtable.client import (
+ BigtableClient as GapicClientType,
+ )
+ from google.cloud.bigtable.data._sync_autogen.client import (
+ _DataApiTarget as TargetType,
+ )
+
+
+class _MutateRowsOperation:
+ """
+ MutateRowsOperation manages the logic of sending a set of row mutations,
+ and retrying on failed entries. It manages this using the _run_attempt
+ function, which attempts to mutate all outstanding entries, and raises
+ _MutateRowsIncomplete if any retryable errors are encountered.
+
+ Errors are exposed as a MutationsExceptionGroup, which contains a list of
+ exceptions organized by the related failed mutation entries.
+
+ Args:
+ gapic_client: the client to use for the mutate_rows call
+ target: the table or view associated with the request
+ mutation_entries: a list of RowMutationEntry objects to send to the server
+ operation_timeout: the timeout to use for the entire operation, in seconds.
+ attempt_timeout: the timeout to use for each mutate_rows attempt, in seconds.
+ If not specified, the request will run until operation_timeout is reached.
+ """
+
+ def __init__(
+ self,
+ gapic_client: GapicClientType,
+ target: TargetType,
+ mutation_entries: list["RowMutationEntry"],
+ operation_timeout: float,
+ attempt_timeout: float | None,
+ retryable_exceptions: Sequence[type[Exception]] = (),
+ ):
+ total_mutations = sum((len(entry.mutations) for entry in mutation_entries))
+ if total_mutations > _MUTATE_ROWS_REQUEST_MUTATION_LIMIT:
+ raise ValueError(
+ f"mutate_rows requests can contain at most {_MUTATE_ROWS_REQUEST_MUTATION_LIMIT} mutations across all entries. Found {total_mutations}."
+ )
+ self._target = target
+ self._gapic_fn = gapic_client.mutate_rows
+ self.is_retryable = retries.if_exception_type(
+ *retryable_exceptions, bt_exceptions._MutateRowsIncomplete
+ )
+ sleep_generator = retries.exponential_sleep_generator(0.01, 2, 60)
+ self._operation = lambda: CrossSync._Sync_Impl.retry_target(
+ self._run_attempt,
+ self.is_retryable,
+ sleep_generator,
+ operation_timeout,
+ exception_factory=_retry_exception_factory,
+ )
+ self.timeout_generator = _attempt_timeout_generator(
+ attempt_timeout, operation_timeout
+ )
+ self.mutations = [_EntryWithProto(m, m._to_pb()) for m in mutation_entries]
+ self.remaining_indices = list(range(len(self.mutations)))
+ self.errors: dict[int, list[Exception]] = {}
+
+ def start(self):
+ """Start the operation, and run until completion
+
+ Raises:
+ MutationsExceptionGroup: if any mutations failed"""
+ try:
+ self._operation()
+ except Exception as exc:
+ incomplete_indices = self.remaining_indices.copy()
+ for idx in incomplete_indices:
+ self._handle_entry_error(idx, exc)
+ finally:
+ all_errors: list[Exception] = []
+ for idx, exc_list in self.errors.items():
+ if len(exc_list) == 0:
+ raise core_exceptions.ClientError(
+ f"Mutation {idx} failed with no associated errors"
+ )
+ elif len(exc_list) == 1:
+ cause_exc = exc_list[0]
+ else:
+ cause_exc = bt_exceptions.RetryExceptionGroup(exc_list)
+ entry = self.mutations[idx].entry
+ all_errors.append(
+ bt_exceptions.FailedMutationEntryError(idx, entry, cause_exc)
+ )
+ if all_errors:
+ raise bt_exceptions.MutationsExceptionGroup(
+ all_errors, len(self.mutations)
+ )
+
+ def _run_attempt(self):
+ """Run a single attempt of the mutate_rows rpc.
+
+ Raises:
+ _MutateRowsIncomplete: if there are failed mutations eligible for
+ retry after the attempt is complete
+ GoogleAPICallError: if the gapic rpc fails"""
+ request_entries = [self.mutations[idx].proto for idx in self.remaining_indices]
+ active_request_indices = {
+ req_idx: orig_idx
+ for (req_idx, orig_idx) in enumerate(self.remaining_indices)
+ }
+ self.remaining_indices = []
+ if not request_entries:
+ return
+ try:
+ result_generator = self._gapic_fn(
+ request=types_pb.MutateRowsRequest(
+ entries=request_entries,
+ app_profile_id=self._target.app_profile_id,
+ **self._target._request_path,
+ ),
+ timeout=next(self.timeout_generator),
+ retry=None,
+ )
+ for result_list in result_generator:
+ for result in result_list.entries:
+ orig_idx = active_request_indices[result.index]
+ entry_error = core_exceptions.from_grpc_status(
+ result.status.code,
+ result.status.message,
+ details=result.status.details,
+ )
+ if result.status.code != 0:
+ self._handle_entry_error(orig_idx, entry_error)
+ elif orig_idx in self.errors:
+ del self.errors[orig_idx]
+ del active_request_indices[result.index]
+ except Exception as exc:
+ for idx in active_request_indices.values():
+ self._handle_entry_error(idx, exc)
+ raise
+ if self.remaining_indices:
+ raise bt_exceptions._MutateRowsIncomplete
+
+ def _handle_entry_error(self, idx: int, exc: Exception):
+ """Add an exception to the list of exceptions for a given mutation index,
+ and add the index to the list of remaining indices if the exception is
+ retryable.
+
+ Args:
+ idx: the index of the mutation that failed
+ exc: the exception to add to the list"""
+ entry = self.mutations[idx].entry
+ self.errors.setdefault(idx, []).append(exc)
+ if (
+ entry.is_idempotent()
+ and self.is_retryable(exc)
+ and (idx not in self.remaining_indices)
+ ):
+ self.remaining_indices.append(idx)
diff --git a/google/cloud/bigtable/data/_sync_autogen/_read_rows.py b/google/cloud/bigtable/data/_sync_autogen/_read_rows.py
new file mode 100644
index 000000000..3593475a9
--- /dev/null
+++ b/google/cloud/bigtable/data/_sync_autogen/_read_rows.py
@@ -0,0 +1,304 @@
+# Copyright 2024 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.
+#
+
+
+# This file is automatically generated by CrossSync. Do not edit manually.
+
+from __future__ import annotations
+from typing import Sequence, TYPE_CHECKING
+from google.cloud.bigtable_v2.types import ReadRowsRequest as ReadRowsRequestPB
+from google.cloud.bigtable_v2.types import ReadRowsResponse as ReadRowsResponsePB
+from google.cloud.bigtable_v2.types import RowSet as RowSetPB
+from google.cloud.bigtable_v2.types import RowRange as RowRangePB
+from google.cloud.bigtable.data.row import Row, Cell
+from google.cloud.bigtable.data.read_rows_query import ReadRowsQuery
+from google.cloud.bigtable.data.exceptions import InvalidChunk
+from google.cloud.bigtable.data.exceptions import _RowSetComplete
+from google.cloud.bigtable.data.exceptions import _ResetRow
+from google.cloud.bigtable.data._helpers import _attempt_timeout_generator
+from google.cloud.bigtable.data._helpers import _retry_exception_factory
+from google.api_core import retry as retries
+from google.api_core.retry import exponential_sleep_generator
+from google.cloud.bigtable.data._cross_sync import CrossSync
+
+if TYPE_CHECKING:
+ from google.cloud.bigtable.data._sync_autogen.client import (
+ _DataApiTarget as TargetType,
+ )
+
+
+class _ReadRowsOperation:
+ """
+ ReadRowsOperation handles the logic of merging chunks from a ReadRowsResponse stream
+ into a stream of Row objects.
+
+ ReadRowsOperation.merge_row_response_stream takes in a stream of ReadRowsResponse
+ and turns them into a stream of Row objects using an internal
+ StateMachine.
+
+ ReadRowsOperation(request, client) handles row merging logic end-to-end, including
+ performing retries on stream errors.
+
+ Args:
+ query: The query to execute
+ target: The table or view to send the request to
+ operation_timeout: The total time to allow for the operation, in seconds
+ attempt_timeout: The time to allow for each individual attempt, in seconds
+ retryable_exceptions: A list of exceptions that should trigger a retry
+ """
+
+ __slots__ = (
+ "attempt_timeout_gen",
+ "operation_timeout",
+ "request",
+ "target",
+ "_predicate",
+ "_last_yielded_row_key",
+ "_remaining_count",
+ )
+
+ def __init__(
+ self,
+ query: ReadRowsQuery,
+ target: TargetType,
+ operation_timeout: float,
+ attempt_timeout: float,
+ retryable_exceptions: Sequence[type[Exception]] = (),
+ ):
+ self.attempt_timeout_gen = _attempt_timeout_generator(
+ attempt_timeout, operation_timeout
+ )
+ self.operation_timeout = operation_timeout
+ if isinstance(query, dict):
+ self.request = ReadRowsRequestPB(
+ **query, **target._request_path, app_profile_id=target.app_profile_id
+ )
+ else:
+ self.request = query._to_pb(target)
+ self.target = target
+ self._predicate = retries.if_exception_type(*retryable_exceptions)
+ self._last_yielded_row_key: bytes | None = None
+ self._remaining_count: int | None = self.request.rows_limit or None
+
+ def start_operation(self) -> CrossSync._Sync_Impl.Iterable[Row]:
+ """Start the read_rows operation, retrying on retryable errors.
+
+ Yields:
+ Row: The next row in the stream"""
+ return CrossSync._Sync_Impl.retry_target_stream(
+ self._read_rows_attempt,
+ self._predicate,
+ exponential_sleep_generator(0.01, 60, multiplier=2),
+ self.operation_timeout,
+ exception_factory=_retry_exception_factory,
+ )
+
+ def _read_rows_attempt(self) -> CrossSync._Sync_Impl.Iterable[Row]:
+ """Attempt a single read_rows rpc call.
+ This function is intended to be wrapped by retry logic,
+ which will call this function until it succeeds or
+ a non-retryable error is raised.
+
+ Yields:
+ Row: The next row in the stream"""
+ if self._last_yielded_row_key is not None:
+ try:
+ self.request.rows = self._revise_request_rowset(
+ row_set=self.request.rows,
+ last_seen_row_key=self._last_yielded_row_key,
+ )
+ except _RowSetComplete:
+ return self.merge_rows(None)
+ if self._remaining_count is not None:
+ self.request.rows_limit = self._remaining_count
+ if self._remaining_count == 0:
+ return self.merge_rows(None)
+ gapic_stream = self.target.client._gapic_client.read_rows(
+ self.request, timeout=next(self.attempt_timeout_gen), retry=None
+ )
+ chunked_stream = self.chunk_stream(gapic_stream)
+ return self.merge_rows(chunked_stream)
+
+ def chunk_stream(
+ self,
+ stream: CrossSync._Sync_Impl.Awaitable[
+ CrossSync._Sync_Impl.Iterable[ReadRowsResponsePB]
+ ],
+ ) -> CrossSync._Sync_Impl.Iterable[ReadRowsResponsePB.CellChunk]:
+ """process chunks out of raw read_rows stream
+
+ Args:
+ stream: the raw read_rows stream from the gapic client
+ Yields:
+ ReadRowsResponsePB.CellChunk: the next chunk in the stream"""
+ for resp in stream:
+ resp = resp._pb
+ if resp.last_scanned_row_key:
+ if (
+ self._last_yielded_row_key is not None
+ and resp.last_scanned_row_key <= self._last_yielded_row_key
+ ):
+ raise InvalidChunk("last scanned out of order")
+ self._last_yielded_row_key = resp.last_scanned_row_key
+ current_key = None
+ for c in resp.chunks:
+ if current_key is None:
+ current_key = c.row_key
+ if current_key is None:
+ raise InvalidChunk("first chunk is missing a row key")
+ elif (
+ self._last_yielded_row_key
+ and current_key <= self._last_yielded_row_key
+ ):
+ raise InvalidChunk("row keys should be strictly increasing")
+ yield c
+ if c.reset_row:
+ current_key = None
+ elif c.commit_row:
+ self._last_yielded_row_key = current_key
+ if self._remaining_count is not None:
+ self._remaining_count -= 1
+ if self._remaining_count < 0:
+ raise InvalidChunk("emit count exceeds row limit")
+ current_key = None
+
+ @staticmethod
+ def merge_rows(
+ chunks: CrossSync._Sync_Impl.Iterable[ReadRowsResponsePB.CellChunk] | None,
+ ) -> CrossSync._Sync_Impl.Iterable[Row]:
+ """Merge chunks into rows
+
+ Args:
+ chunks: the chunk stream to merge
+ Yields:
+ Row: the next row in the stream"""
+ if chunks is None:
+ return
+ it = chunks.__iter__()
+ while True:
+ try:
+ c = it.__next__()
+ except CrossSync._Sync_Impl.StopIteration:
+ return
+ row_key = c.row_key
+ if not row_key:
+ raise InvalidChunk("first row chunk is missing key")
+ cells = []
+ family: str | None = None
+ qualifier: bytes | None = None
+ try:
+ while True:
+ if c.reset_row:
+ raise _ResetRow(c)
+ k = c.row_key
+ f = c.family_name.value
+ q = c.qualifier.value if c.HasField("qualifier") else None
+ if k and k != row_key:
+ raise InvalidChunk("unexpected new row key")
+ if f:
+ family = f
+ if q is not None:
+ qualifier = q
+ else:
+ raise InvalidChunk("new family without qualifier")
+ elif family is None:
+ raise InvalidChunk("missing family")
+ elif q is not None:
+ if family is None:
+ raise InvalidChunk("new qualifier without family")
+ qualifier = q
+ elif qualifier is None:
+ raise InvalidChunk("missing qualifier")
+ ts = c.timestamp_micros
+ labels = c.labels if c.labels else []
+ value = c.value
+ if c.value_size > 0:
+ buffer = [value]
+ while c.value_size > 0:
+ c = it.__next__()
+ t = c.timestamp_micros
+ cl = c.labels
+ k = c.row_key
+ if (
+ c.HasField("family_name")
+ and c.family_name.value != family
+ ):
+ raise InvalidChunk("family changed mid cell")
+ if (
+ c.HasField("qualifier")
+ and c.qualifier.value != qualifier
+ ):
+ raise InvalidChunk("qualifier changed mid cell")
+ if t and t != ts:
+ raise InvalidChunk("timestamp changed mid cell")
+ if cl and cl != labels:
+ raise InvalidChunk("labels changed mid cell")
+ if k and k != row_key:
+ raise InvalidChunk("row key changed mid cell")
+ if c.reset_row:
+ raise _ResetRow(c)
+ buffer.append(c.value)
+ value = b"".join(buffer)
+ cells.append(
+ Cell(value, row_key, family, qualifier, ts, list(labels))
+ )
+ if c.commit_row:
+ yield Row(row_key, cells)
+ break
+ c = it.__next__()
+ except _ResetRow as e:
+ c = e.chunk
+ if (
+ c.row_key
+ or c.HasField("family_name")
+ or c.HasField("qualifier")
+ or c.timestamp_micros
+ or c.labels
+ or c.value
+ ):
+ raise InvalidChunk("reset row with data")
+ continue
+ except CrossSync._Sync_Impl.StopIteration:
+ raise InvalidChunk("premature end of stream")
+
+ @staticmethod
+ def _revise_request_rowset(row_set: RowSetPB, last_seen_row_key: bytes) -> RowSetPB:
+ """Revise the rows in the request to avoid ones we've already processed.
+
+ Args:
+ row_set: the row set from the request
+ last_seen_row_key: the last row key encountered
+ Returns:
+ RowSetPB: the new rowset after adusting for the last seen key
+ Raises:
+ _RowSetComplete: if there are no rows left to process after the revision"""
+ if row_set is None or (not row_set.row_ranges and (not row_set.row_keys)):
+ last_seen = last_seen_row_key
+ return RowSetPB(row_ranges=[RowRangePB(start_key_open=last_seen)])
+ adjusted_keys: list[bytes] = [
+ k for k in row_set.row_keys if k > last_seen_row_key
+ ]
+ adjusted_ranges: list[RowRangePB] = []
+ for row_range in row_set.row_ranges:
+ end_key = row_range.end_key_closed or row_range.end_key_open or None
+ if end_key is None or end_key > last_seen_row_key:
+ new_range = RowRangePB(row_range)
+ start_key = row_range.start_key_closed or row_range.start_key_open
+ if start_key is None or start_key <= last_seen_row_key:
+ new_range.start_key_open = last_seen_row_key
+ adjusted_ranges.append(new_range)
+ if len(adjusted_keys) == 0 and len(adjusted_ranges) == 0:
+ raise _RowSetComplete()
+ return RowSetPB(row_keys=adjusted_keys, row_ranges=adjusted_ranges)
diff --git a/google/cloud/bigtable/data/_sync_autogen/_swappable_channel.py b/google/cloud/bigtable/data/_sync_autogen/_swappable_channel.py
new file mode 100644
index 000000000..78ba129d9
--- /dev/null
+++ b/google/cloud/bigtable/data/_sync_autogen/_swappable_channel.py
@@ -0,0 +1,96 @@
+# Copyright 2023 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.
+#
+
+# This file is automatically generated by CrossSync. Do not edit manually.
+
+from __future__ import annotations
+from typing import Callable
+from grpc import ChannelConnectivity
+from grpc import Channel
+
+
+class _WrappedChannel(Channel):
+ """
+ A wrapper around a gRPC channel. All methods are passed
+ through to the underlying channel.
+ """
+
+ def __init__(self, channel: Channel):
+ self._channel = channel
+
+ def unary_unary(self, *args, **kwargs):
+ return self._channel.unary_unary(*args, **kwargs)
+
+ def unary_stream(self, *args, **kwargs):
+ return self._channel.unary_stream(*args, **kwargs)
+
+ def stream_unary(self, *args, **kwargs):
+ return self._channel.stream_unary(*args, **kwargs)
+
+ def stream_stream(self, *args, **kwargs):
+ return self._channel.stream_stream(*args, **kwargs)
+
+ def channel_ready(self):
+ return self._channel.channel_ready()
+
+ def __enter__(self):
+ self._channel.__enter__()
+ return self
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ return self._channel.__exit__(exc_type, exc_val, exc_tb)
+
+ def get_state(self, try_to_connect: bool = False) -> ChannelConnectivity:
+ return self._channel.get_state(try_to_connect=try_to_connect)
+
+ def wait_for_state_change(self, last_observed_state):
+ return self._channel.wait_for_state_change(last_observed_state)
+
+ def __getattr__(self, name):
+ return getattr(self._channel, name)
+
+ def close(self, grace=None):
+ return self._channel.close()
+
+ def subscribe(self, callback, try_to_connect=False):
+ return self._channel.subscribe(callback, try_to_connect)
+
+ def unsubscribe(self, callback):
+ return self._channel.unsubscribe(callback)
+
+
+class SwappableChannel(_WrappedChannel):
+ """
+ Provides a grpc channel wrapper, that allows the internal channel to be swapped out
+
+ Args:
+ - channel_fn: a nullary function that returns a new channel instance.
+ It should be a partial with all channel configuration arguments built-in
+ """
+
+ def __init__(self, channel_fn: Callable[[], Channel]):
+ self._channel_fn = channel_fn
+ self._channel = channel_fn()
+
+ def create_channel(self) -> Channel:
+ """Create a fresh channel using the stored `channel_fn` partial"""
+ new_channel = self._channel_fn()
+ return new_channel
+
+ def swap_channel(self, new_channel: Channel) -> Channel:
+ """Replace the wrapped channel with a new instance. Typically created using `create_channel`"""
+ old_channel = self._channel
+ self._channel = new_channel
+ return old_channel
diff --git a/google/cloud/bigtable/data/_sync_autogen/client.py b/google/cloud/bigtable/data/_sync_autogen/client.py
new file mode 100644
index 000000000..622002763
--- /dev/null
+++ b/google/cloud/bigtable/data/_sync_autogen/client.py
@@ -0,0 +1,1589 @@
+# Copyright 2024 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.
+#
+
+
+# This file is automatically generated by CrossSync. Do not edit manually.
+
+from __future__ import annotations
+from typing import cast, Any, Callable, Optional, Set, Sequence, TYPE_CHECKING
+import abc
+import time
+import warnings
+import random
+import os
+import concurrent.futures
+from functools import partial
+from grpc import Channel
+from google.cloud.bigtable.data.execute_query.values import ExecuteQueryValueType
+from google.cloud.bigtable.data.execute_query.metadata import (
+ SqlType,
+ _pb_metadata_to_metadata_types,
+)
+from google.cloud.bigtable.data.execute_query._parameters_formatting import (
+ _format_execute_query_params,
+ _to_param_types,
+)
+from google.cloud.bigtable_v2.services.bigtable.transports.base import (
+ DEFAULT_CLIENT_INFO,
+)
+from google.cloud.bigtable_v2.types.bigtable import PingAndWarmRequest
+from google.cloud.bigtable_v2.types.bigtable import SampleRowKeysRequest
+from google.cloud.bigtable_v2.types.bigtable import MutateRowRequest
+from google.cloud.bigtable_v2.types.bigtable import CheckAndMutateRowRequest
+from google.cloud.bigtable_v2.types.bigtable import ReadModifyWriteRowRequest
+from google.cloud.client import ClientWithProject
+from google.cloud.environment_vars import BIGTABLE_EMULATOR
+from google.api_core import retry as retries
+from google.api_core.exceptions import DeadlineExceeded
+from google.api_core.exceptions import ServiceUnavailable
+from google.api_core.exceptions import Aborted
+from google.api_core.exceptions import Cancelled
+from google.protobuf.message import Message
+from google.protobuf.internal.enum_type_wrapper import EnumTypeWrapper
+import google.auth.credentials
+import google.auth._default
+from google.api_core import client_options as client_options_lib
+from google.cloud.bigtable.client import _DEFAULT_BIGTABLE_EMULATOR_CLIENT
+from google.cloud.bigtable.data.row import Row
+from google.cloud.bigtable.data.read_rows_query import ReadRowsQuery
+from google.cloud.bigtable.data.exceptions import FailedQueryShardError
+from google.cloud.bigtable.data.exceptions import ShardedReadRowsExceptionGroup
+from google.cloud.bigtable.data._helpers import TABLE_DEFAULT, _align_timeouts
+from google.cloud.bigtable.data._helpers import _WarmedInstanceKey
+from google.cloud.bigtable.data._helpers import _CONCURRENCY_LIMIT
+from google.cloud.bigtable.data._helpers import _retry_exception_factory
+from google.cloud.bigtable.data._helpers import _validate_timeouts
+from google.cloud.bigtable.data._helpers import _get_error_type
+from google.cloud.bigtable.data._helpers import _get_retryable_errors
+from google.cloud.bigtable.data._helpers import _get_timeouts
+from google.cloud.bigtable.data._helpers import _attempt_timeout_generator
+from google.cloud.bigtable.data.mutations import Mutation, RowMutationEntry
+from google.cloud.bigtable.data.read_modify_write_rules import ReadModifyWriteRule
+from google.cloud.bigtable.data.row_filters import RowFilter
+from google.cloud.bigtable.data.row_filters import StripValueTransformerFilter
+from google.cloud.bigtable.data.row_filters import CellsRowLimitFilter
+from google.cloud.bigtable.data.row_filters import RowFilterChain
+from google.cloud.bigtable.data._metrics import BigtableClientSideMetricsController
+from google.cloud.bigtable.data._cross_sync import CrossSync
+from typing import Iterable
+from grpc import insecure_channel
+from grpc import intercept_channel
+from google.cloud.bigtable_v2.services.bigtable.transports import (
+ BigtableGrpcTransport as TransportType,
+)
+from google.cloud.bigtable_v2.services.bigtable import BigtableClient as GapicClient
+from google.cloud.bigtable.data._sync_autogen.mutations_batcher import _MB_SIZE
+from google.cloud.bigtable.data._sync_autogen._swappable_channel import (
+ SwappableChannel as SwappableChannelType,
+)
+from google.cloud.bigtable.data._sync_autogen.metrics_interceptor import (
+ BigtableMetricsInterceptor as MetricsInterceptorType,
+)
+
+if TYPE_CHECKING:
+ from google.cloud.bigtable.data._helpers import RowKeySamples
+ from google.cloud.bigtable.data._helpers import ShardedQuery
+ from google.cloud.bigtable.data._sync_autogen.mutations_batcher import (
+ MutationsBatcher,
+ )
+ from google.cloud.bigtable.data.execute_query._sync_autogen.execute_query_iterator import (
+ ExecuteQueryIterator,
+ )
+
+
+@CrossSync._Sync_Impl.add_mapping_decorator("DataClient")
+class BigtableDataClient(ClientWithProject):
+ def __init__(
+ self,
+ *,
+ project: str | None = None,
+ credentials: google.auth.credentials.Credentials | None = None,
+ client_options: dict[str, Any]
+ | "google.api_core.client_options.ClientOptions"
+ | None = None,
+ **kwargs,
+ ):
+ """Create a client instance for the Bigtable Data API
+
+
+
+ Args:
+ project: the project which the client acts on behalf of.
+ If not passed, falls back to the default inferred
+ from the environment.
+ credentials:
+ Thehe OAuth2 Credentials to use for this
+ client. If not passed (and if no ``_http`` object is
+ passed), falls back to the default inferred from the
+ environment.
+ client_options:
+ Client options used to set user options
+ on the client. API Endpoint should be set through client_options.
+ Raises:
+ """
+ if "pool_size" in kwargs:
+ warnings.warn("pool_size no longer supported")
+ self.client_info = DEFAULT_CLIENT_INFO
+ self.client_info.client_library_version = self._client_version()
+ if type(client_options) is dict:
+ client_options = client_options_lib.from_dict(client_options)
+ client_options = cast(
+ Optional[client_options_lib.ClientOptions], client_options
+ )
+ self._emulator_host = os.getenv(BIGTABLE_EMULATOR)
+ if self._emulator_host is not None:
+ warnings.warn(
+ "Connecting to Bigtable emulator at {}".format(self._emulator_host),
+ RuntimeWarning,
+ stacklevel=2,
+ )
+ if credentials is None:
+ credentials = google.auth.credentials.AnonymousCredentials()
+ if project is None:
+ project = _DEFAULT_BIGTABLE_EMULATOR_CLIENT
+ self._metrics_interceptor = MetricsInterceptorType()
+ ClientWithProject.__init__(
+ self,
+ credentials=credentials,
+ project=project,
+ client_options=client_options,
+ )
+ self._gapic_client = GapicClient(
+ credentials=credentials,
+ client_options=client_options,
+ client_info=self.client_info,
+ transport=lambda *args, **kwargs: TransportType(
+ *args, **kwargs, channel=self._build_grpc_channel
+ ),
+ )
+ if (
+ credentials
+ and credentials.universe_domain != self.universe_domain
+ and (self._emulator_host is None)
+ ):
+ raise ValueError(
+ f"The configured universe domain ({self.universe_domain}) does not match the universe domain found in the credentials ({self._credentials.universe_domain}). If you haven't configured the universe domain explicitly, `googleapis.com` is the default."
+ )
+ self._is_closed = CrossSync._Sync_Impl.Event()
+ self.transport = cast(TransportType, self._gapic_client.transport)
+ self._active_instances: Set[_WarmedInstanceKey] = set()
+ self._instance_owners: dict[_WarmedInstanceKey, Set[int]] = {}
+ self._channel_init_time = time.monotonic()
+ self._channel_refresh_task: CrossSync._Sync_Impl.Task[None] | None = None
+ self._executor: concurrent.futures.ThreadPoolExecutor | None = (
+ concurrent.futures.ThreadPoolExecutor()
+ if not CrossSync._Sync_Impl.is_async
+ else None
+ )
+ if self._emulator_host is None:
+ try:
+ self._start_background_channel_refresh()
+ except RuntimeError:
+ warnings.warn(
+ f"{self.__class__.__name__} should be started in an asyncio event loop. Channel refresh will not be started",
+ RuntimeWarning,
+ stacklevel=2,
+ )
+
+ def _build_grpc_channel(self, *args, **kwargs) -> SwappableChannelType:
+ """This method is called by the gapic transport to create a grpc channel.
+
+ The init arguments passed down are captured in a partial used by SwappableChannel
+ to create new channel instances in the future, as part of the channel refresh logic
+
+ Emulators always use an inseucre channel
+
+ Args:
+ - *args: positional arguments passed by the gapic layer to create a new channel with
+ - **kwargs: keyword arguments passed by the gapic layer to create a new channel with
+ Returns:
+ a custom wrapped swappable channel"""
+ create_channel_fn: Callable[[], Channel]
+ if self._emulator_host is not None:
+ create_channel_fn = partial(insecure_channel, self._emulator_host)
+ else:
+
+ def sync_create_channel_fn():
+ return intercept_channel(
+ TransportType.create_channel(*args, **kwargs),
+ self._metrics_interceptor,
+ )
+
+ create_channel_fn = sync_create_channel_fn
+ new_channel = SwappableChannelType(create_channel_fn)
+ return new_channel
+
+ @property
+ def universe_domain(self) -> str:
+ """Return the universe domain used by the client instance.
+
+ Returns:
+ str: The universe domain used by the client instance."""
+ return self._gapic_client.universe_domain
+
+ @property
+ def api_endpoint(self) -> str:
+ """Return the API endpoint used by the client instance.
+
+ Returns:
+ str: The API endpoint used by the client instance."""
+ return self._gapic_client.api_endpoint
+
+ @staticmethod
+ def _client_version() -> str:
+ """Helper function to return the client version string for this client"""
+ version_str = f"{google.cloud.bigtable.__version__}-data"
+ return version_str
+
+ def _start_background_channel_refresh(self) -> None:
+ """Starts a background task to ping and warm grpc channel
+
+ Raises:
+ None"""
+ if (
+ not self._channel_refresh_task
+ and (not self._emulator_host)
+ and (not self._is_closed.is_set())
+ ):
+ CrossSync._Sync_Impl.verify_async_event_loop()
+ self._channel_refresh_task = CrossSync._Sync_Impl.create_task(
+ self._manage_channel,
+ sync_executor=self._executor,
+ task_name=f"{self.__class__.__name__} channel refresh",
+ )
+
+ def close(self, timeout: float | None = 2.0):
+ """Cancel all background tasks"""
+ self._is_closed.set()
+ if self._channel_refresh_task is not None:
+ self._channel_refresh_task.cancel()
+ CrossSync._Sync_Impl.wait([self._channel_refresh_task], timeout=timeout)
+ self.transport.close()
+ if self._executor:
+ self._executor.shutdown(wait=False)
+ self._channel_refresh_task = None
+
+ def _ping_and_warm_instances(
+ self,
+ instance_key: _WarmedInstanceKey | None = None,
+ channel: Channel | None = None,
+ ) -> list[BaseException | None]:
+ """Prepares the backend for requests on a channel
+
+ Pings each Bigtable instance registered in `_active_instances` on the client
+
+ Args:
+ instance_key: if provided, only warm the instance associated with the key
+ channel: grpc channel to warm. If none, warms `self.transport.grpc_channel`
+ Returns:
+ list[BaseException | None]: sequence of results or exceptions from the ping requests
+ """
+ channel = channel or self.transport.grpc_channel
+ instance_list = (
+ [instance_key] if instance_key is not None else self._active_instances
+ )
+ ping_rpc = channel.unary_unary(
+ "/google.bigtable.v2.Bigtable/PingAndWarm",
+ request_serializer=PingAndWarmRequest.serialize,
+ )
+ partial_list = [
+ partial(
+ ping_rpc,
+ request={"name": instance_name, "app_profile_id": app_profile_id},
+ metadata=[
+ (
+ "x-goog-request-params",
+ f"name={instance_name}&app_profile_id={app_profile_id}",
+ )
+ ],
+ wait_for_ready=True,
+ )
+ for (instance_name, app_profile_id) in instance_list
+ ]
+ result_list = CrossSync._Sync_Impl.gather_partials(
+ partial_list, return_exceptions=True, sync_executor=self._executor
+ )
+ return [r or None for r in result_list]
+
+ def _invalidate_channel_stubs(self):
+ """Helper to reset the cached stubs. Needed when changing out the grpc channel"""
+ self.transport._stubs = {}
+ self.transport._prep_wrapped_messages(self.client_info)
+
+ def _manage_channel(
+ self,
+ refresh_interval_min: float = 60 * 35,
+ refresh_interval_max: float = 60 * 45,
+ grace_period: float = 60 * 10,
+ ) -> None:
+ """Background task that periodically refreshes and warms a grpc channel
+
+ The backend will automatically close channels after 60 minutes, so
+ `refresh_interval` + `grace_period` should be < 60 minutes
+
+ Runs continuously until the client is closed
+
+ Args:
+ refresh_interval_min: minimum interval before initiating refresh
+ process in seconds. Actual interval will be a random value
+ between `refresh_interval_min` and `refresh_interval_max`
+ refresh_interval_max: maximum interval before initiating refresh
+ process in seconds. Actual interval will be a random value
+ between `refresh_interval_min` and `refresh_interval_max`
+ grace_period: time to allow previous channel to serve existing
+ requests before closing, in seconds"""
+ if not isinstance(self.transport.grpc_channel, SwappableChannelType):
+ warnings.warn("Channel does not support auto-refresh.")
+ return
+ super_channel: SwappableChannelType = self.transport.grpc_channel
+ first_refresh = self._channel_init_time + random.uniform(
+ refresh_interval_min, refresh_interval_max
+ )
+ next_sleep = max(first_refresh - time.monotonic(), 0)
+ if next_sleep > 0:
+ self._ping_and_warm_instances(channel=super_channel)
+ while not self._is_closed.is_set():
+ CrossSync._Sync_Impl.event_wait(
+ self._is_closed, next_sleep, async_break_early=False
+ )
+ if self._is_closed.is_set():
+ break
+ start_timestamp = time.monotonic()
+ new_channel = super_channel.create_channel()
+ self._ping_and_warm_instances(channel=new_channel)
+ old_channel = super_channel.swap_channel(new_channel)
+ self._invalidate_channel_stubs()
+ if grace_period:
+ CrossSync._Sync_Impl.event_wait(
+ self._is_closed, grace_period, async_break_early=False
+ )
+ old_channel.close()
+ next_refresh = random.uniform(refresh_interval_min, refresh_interval_max)
+ next_sleep = max(next_refresh - (time.monotonic() - start_timestamp), 0)
+
+ def _register_instance(
+ self, instance_id: str, app_profile_id: Optional[str], owner_id: int
+ ) -> None:
+ """Registers an instance with the client, and warms the channel for the instance
+ The client will periodically refresh grpc channel used to make
+ requests, and new channels will be warmed for each registered instance
+ Channels will not be refreshed unless at least one instance is registered
+
+ Args:
+ instance_id: id of the instance to register.
+ app_profile_id: id of the app profile calling the instance.
+ owner_id: integer id of the object owning the instance. Owners will be tracked in
+ _instance_owners, and instances will only be unregistered when all
+ owners call _remove_instance_registration. Can be obtained by calling
+ `id` identity funcion, using `id(owner)`"""
+ instance_name = self._gapic_client.instance_path(self.project, instance_id)
+ instance_key = _WarmedInstanceKey(instance_name, app_profile_id)
+ self._instance_owners.setdefault(instance_key, set()).add(owner_id)
+ if instance_key not in self._active_instances:
+ self._active_instances.add(instance_key)
+ if self._channel_refresh_task:
+ self._ping_and_warm_instances(instance_key)
+ else:
+ self._start_background_channel_refresh()
+
+ def _remove_instance_registration(
+ self, instance_id: str, app_profile_id: Optional[str], owner_id: int
+ ) -> bool:
+ """Removes an instance from the client's registered instances, to prevent
+ warming new channels for the instance
+
+ If instance_id is not registered, or is still in use by other tables, returns False
+
+ Args:
+ instance_id: id of the instance to remove
+ app_profile_id: id of the app profile calling the instance.
+ owner_id: integer id of the object owning the instance. Can be
+ obtained by the `id` identity funcion, using `id(owner)`.
+ Returns:
+ bool: True if instance was removed, else False"""
+ instance_name = self._gapic_client.instance_path(self.project, instance_id)
+ instance_key = _WarmedInstanceKey(instance_name, app_profile_id)
+ owner_list = self._instance_owners.get(instance_key, set())
+ try:
+ owner_list.remove(owner_id)
+ if len(owner_list) == 0:
+ self._active_instances.remove(instance_key)
+ return True
+ except KeyError:
+ return False
+
+ def get_table(self, instance_id: str, table_id: str, *args, **kwargs) -> Table:
+ """Returns a table instance for making data API requests. All arguments are passed
+ directly to the Table constructor.
+
+
+
+ Args:
+ instance_id: The Bigtable instance ID to associate with this client.
+ instance_id is combined with the client's project to fully
+ specify the instance
+ table_id: The ID of the table. table_id is combined with the
+ instance_id and the client's project to fully specify the table
+ app_profile_id: The app profile to associate with requests.
+ https://cloud.google.com/bigtable/docs/app-profiles
+ default_read_rows_operation_timeout: The default timeout for read rows
+ operations, in seconds. If not set, defaults to 600 seconds (10 minutes)
+ default_read_rows_attempt_timeout: The default timeout for individual
+ read rows rpc requests, in seconds. If not set, defaults to 20 seconds
+ default_mutate_rows_operation_timeout: The default timeout for mutate rows
+ operations, in seconds. If not set, defaults to 600 seconds (10 minutes)
+ default_mutate_rows_attempt_timeout: The default timeout for individual
+ mutate rows rpc requests, in seconds. If not set, defaults to 60 seconds
+ default_operation_timeout: The default timeout for all other operations, in
+ seconds. If not set, defaults to 60 seconds
+ default_attempt_timeout: The default timeout for all other individual rpc
+ requests, in seconds. If not set, defaults to 20 seconds
+ default_read_rows_retryable_errors: a list of errors that will be retried
+ if encountered during read_rows and related operations.
+ Defaults to 4 (DeadlineExceeded), 14 (ServiceUnavailable), and 10 (Aborted)
+ default_mutate_rows_retryable_errors: a list of errors that will be retried
+ if encountered during mutate_rows and related operations.
+ Defaults to 4 (DeadlineExceeded) and 14 (ServiceUnavailable)
+ default_retryable_errors: a list of errors that will be retried if
+ encountered during all other operations.
+ Defaults to 4 (DeadlineExceeded) and 14 (ServiceUnavailable)
+ Returns:
+ Table: a table instance for making data API requests
+ Raises:
+ None"""
+ return Table(self, instance_id, table_id, *args, **kwargs)
+
+ def get_authorized_view(
+ self, instance_id: str, table_id: str, authorized_view_id: str, *args, **kwargs
+ ) -> AuthorizedView:
+ """Returns an authorized view instance for making data API requests. All arguments are passed
+ directly to the AuthorizedView constructor.
+
+
+
+ Args:
+ instance_id: The Bigtable instance ID to associate with this client.
+ instance_id is combined with the client's project to fully
+ specify the instance
+ table_id: The ID of the table. table_id is combined with the
+ instance_id and the client's project to fully specify the table
+ authorized_view_id: The id for the authorized view to use for requests
+ app_profile_id: The app profile to associate with requests.
+ https://cloud.google.com/bigtable/docs/app-profiles
+ default_read_rows_operation_timeout: The default timeout for read rows
+ operations, in seconds. If not set, defaults to Table's value
+ default_read_rows_attempt_timeout: The default timeout for individual
+ read rows rpc requests, in seconds. If not set, defaults Table's value
+ default_mutate_rows_operation_timeout: The default timeout for mutate rows
+ operations, in seconds. If not set, defaults to Table's value
+ default_mutate_rows_attempt_timeout: The default timeout for individual
+ mutate rows rpc requests, in seconds. If not set, defaults Table's value
+ default_operation_timeout: The default timeout for all other operations, in
+ seconds. If not set, defaults to Table's value
+ default_attempt_timeout: The default timeout for all other individual rpc
+ requests, in seconds. If not set, defaults to Table's value
+ default_read_rows_retryable_errors: a list of errors that will be retried
+ if encountered during read_rows and related operations. If not set,
+ defaults to Table's value
+ default_mutate_rows_retryable_errors: a list of errors that will be retried
+ if encountered during mutate_rows and related operations. If not set,
+ defaults to Table's value
+ default_retryable_errors: a list of errors that will be retried if
+ encountered during all other operations. If not set, defaults to
+ Table's value
+ Returns:
+ AuthorizedView: a table instance for making data API requests
+ Raises:
+ None"""
+ return CrossSync._Sync_Impl.AuthorizedView(
+ self, instance_id, table_id, authorized_view_id, *args, **kwargs
+ )
+
+ def execute_query(
+ self,
+ query: str,
+ instance_id: str,
+ *,
+ parameters: dict[str, ExecuteQueryValueType] | None = None,
+ parameter_types: dict[str, SqlType.Type] | None = None,
+ app_profile_id: str | None = None,
+ operation_timeout: float = 600,
+ attempt_timeout: float | None = 20,
+ retryable_errors: Sequence[type[Exception]] = (
+ DeadlineExceeded,
+ ServiceUnavailable,
+ Aborted,
+ ),
+ prepare_operation_timeout: float = 60,
+ prepare_attempt_timeout: float | None = 20,
+ prepare_retryable_errors: Sequence[type[Exception]] = (
+ DeadlineExceeded,
+ ServiceUnavailable,
+ ),
+ column_info: dict[str, Message | EnumTypeWrapper] | None = None,
+ ) -> "ExecuteQueryIterator":
+ """Executes an SQL query on an instance.
+ Returns an iterator to asynchronously stream back columns from selected rows.
+
+ Failed requests within operation_timeout will be retried based on the
+ retryable_errors list until operation_timeout is reached.
+
+ Note that this makes two requests, one to ``PrepareQuery`` and one to ``ExecuteQuery``.
+ These have separate retry configurations. ``ExecuteQuery`` is where the bulk of the
+ work happens.
+
+ Args:
+ query: Query to be run on Bigtable instance. The query can use ``@param``
+ placeholders to use parameter interpolation on the server. Values for all
+ parameters should be provided in ``parameters``. Types of parameters are
+ inferred but should be provided in ``parameter_types`` if the inference is
+ not possible (i.e. when value can be None, an empty list or an empty dict).
+ instance_id: The Bigtable instance ID to perform the query on.
+ instance_id is combined with the client's project to fully
+ specify the instance.
+ parameters: Dictionary with values for all parameters used in the ``query``.
+ parameter_types: Dictionary with types of parameters used in the ``query``.
+ Required to contain entries only for parameters whose type cannot be
+ detected automatically (i.e. the value can be None, an empty list or
+ an empty dict).
+ app_profile_id: The app profile to associate with requests.
+ https://cloud.google.com/bigtable/docs/app-profiles
+ operation_timeout: the time budget for the entire executeQuery operation, in seconds.
+ Failed requests will be retried within the budget.
+ Defaults to 600 seconds.
+ attempt_timeout: the time budget for an individual executeQuery network request, in seconds.
+ If it takes longer than this time to complete, the request will be cancelled with
+ a DeadlineExceeded exception, and a retry will be attempted.
+ Defaults to the 20 seconds.
+ If None, defaults to operation_timeout.
+ retryable_errors: a list of errors that will be retried if encountered during executeQuery.
+ Defaults to 4 (DeadlineExceeded), 14 (ServiceUnavailable), and 10 (Aborted)
+ prepare_operation_timeout: the time budget for the entire prepareQuery operation, in seconds.
+ Failed requests will be retried within the budget.
+ Defaults to 60 seconds.
+ prepare_attempt_timeout: the time budget for an individual prepareQuery network request, in seconds.
+ If it takes longer than this time to complete, the request will be cancelled with
+ a DeadlineExceeded exception, and a retry will be attempted.
+ Defaults to the 20 seconds.
+ If None, defaults to prepare_operation_timeout.
+ prepare_retryable_errors: a list of errors that will be retried if encountered during prepareQuery.
+ Defaults to 4 (DeadlineExceeded) and 14 (ServiceUnavailable)
+ column_info: (Optional) A dictionary mapping column names to Protobuf message classes or EnumTypeWrapper objects.
+ This dictionary provides the necessary type information for deserializing PROTO and
+ ENUM column values from the query results. When an entry is provided
+ for a PROTO or ENUM column, the client library will attempt to deserialize the raw data.
+
+ - For PROTO columns: The value in the dictionary should be the
+ Protobuf Message class (e.g., ``my_pb2.MyMessage``).
+ - For ENUM columns: The value should be the Protobuf EnumTypeWrapper
+ object (e.g., ``my_pb2.MyEnum``).
+
+ Example::
+
+ import my_pb2
+
+ column_info = {
+ "my_proto_column": my_pb2.MyMessage,
+ "my_enum_column": my_pb2.MyEnum
+ }
+
+ If ``column_info`` is not provided, or if a specific column name is not found
+ in the dictionary:
+
+ - PROTO columns will be returned as raw bytes.
+ - ENUM columns will be returned as integers.
+
+ Note for Nested PROTO or ENUM Fields:
+
+ To specify types for PROTO or ENUM fields within STRUCTs or MAPs, use a dot-separated
+ path from the top-level column name.
+
+ - For STRUCTs: ``struct_column_name.field_name``
+ - For MAPs: ``map_column_name.key`` or ``map_column_name.value`` to specify types
+ for the map keys or values, respectively.
+
+ Example::
+
+ import my_pb2
+
+ column_info = {
+ # Top-level column
+ "my_proto_column": my_pb2.MyMessage,
+ "my_enum_column": my_pb2.MyEnum,
+
+ # Nested field in a STRUCT column named 'my_struct'
+ "my_struct.nested_proto_field": my_pb2.OtherMessage,
+ "my_struct.nested_enum_field": my_pb2.AnotherEnum,
+
+ # Nested field in a MAP column named 'my_map'
+ "my_map.key": my_pb2.MapKeyEnum, # If map keys were enums
+ "my_map.value": my_pb2.MapValueMessage,
+
+ # PROTO field inside a STRUCT, where the STRUCT is the value in a MAP column
+ "struct_map.value.nested_proto_field": my_pb2.DeeplyNestedProto,
+ "struct_map.value.nested_enum_field": my_pb2.DeeplyNestedEnum
+ }
+
+ Returns:
+ ExecuteQueryIterator: an asynchronous iterator that yields rows returned by the query
+ Raises:
+ google.api_core.exceptions.DeadlineExceeded: raised after operation timeout
+ will be chained with a RetryExceptionGroup containing GoogleAPIError exceptions
+ from any retries that failed
+ google.api_core.exceptions.GoogleAPIError: raised if the request encounters an unrecoverable error
+ google.cloud.bigtable.data.exceptions.ParameterTypeInferenceFailed: Raised if
+ a parameter is passed without an explicit type, and the type cannot be infered
+ google.protobuf.message.DecodeError: raised if the deserialization of a PROTO/ENUM value fails.
+ """
+ instance_name = self._gapic_client.instance_path(self.project, instance_id)
+ converted_param_types = _to_param_types(parameters, parameter_types)
+ prepare_request = {
+ "instance_name": instance_name,
+ "query": query,
+ "app_profile_id": app_profile_id,
+ "param_types": converted_param_types,
+ "proto_format": {},
+ }
+ prepare_predicate = retries.if_exception_type(
+ *[_get_error_type(e) for e in prepare_retryable_errors]
+ )
+ (prepare_operation_timeout, prepare_attempt_timeout) = _align_timeouts(
+ prepare_operation_timeout, prepare_attempt_timeout
+ )
+ prepare_sleep_generator = retries.exponential_sleep_generator(0.01, 2, 60)
+ target = partial(
+ self._gapic_client.prepare_query,
+ request=prepare_request,
+ timeout=prepare_attempt_timeout,
+ retry=None,
+ )
+ prepare_result = CrossSync._Sync_Impl.retry_target(
+ target,
+ prepare_predicate,
+ prepare_sleep_generator,
+ prepare_operation_timeout,
+ exception_factory=_retry_exception_factory,
+ )
+ prepare_metadata = _pb_metadata_to_metadata_types(prepare_result.metadata)
+ retryable_excs = [_get_error_type(e) for e in retryable_errors]
+ pb_params = _format_execute_query_params(parameters, parameter_types)
+ request_body = {
+ "instance_name": instance_name,
+ "app_profile_id": app_profile_id,
+ "prepared_query": prepare_result.prepared_query,
+ "params": pb_params,
+ }
+ (operation_timeout, attempt_timeout) = _align_timeouts(
+ operation_timeout, attempt_timeout
+ )
+ return CrossSync._Sync_Impl.ExecuteQueryIterator(
+ self,
+ instance_id,
+ app_profile_id,
+ request_body,
+ prepare_metadata,
+ attempt_timeout,
+ operation_timeout,
+ retryable_excs=retryable_excs,
+ column_info=column_info,
+ )
+
+ def __enter__(self):
+ self._start_background_channel_refresh()
+ return self
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ self.close()
+ self._gapic_client.__exit__(exc_type, exc_val, exc_tb)
+
+
+class _DataApiTarget(abc.ABC):
+ """
+ Abstract class containing API surface for BigtableDataClient. Should not be created directly
+
+ Can be instantiated as a Table or an AuthorizedView
+ """
+
+ def __init__(
+ self,
+ client: BigtableDataClient,
+ instance_id: str,
+ table_id: str,
+ app_profile_id: str | None = None,
+ *,
+ default_read_rows_operation_timeout: float = 600,
+ default_read_rows_attempt_timeout: float | None = 20,
+ default_mutate_rows_operation_timeout: float = 600,
+ default_mutate_rows_attempt_timeout: float | None = 60,
+ default_operation_timeout: float = 60,
+ default_attempt_timeout: float | None = 20,
+ default_read_rows_retryable_errors: Sequence[type[Exception]] = (
+ DeadlineExceeded,
+ ServiceUnavailable,
+ Aborted,
+ Cancelled,
+ ),
+ default_mutate_rows_retryable_errors: Sequence[type[Exception]] = (
+ DeadlineExceeded,
+ ServiceUnavailable,
+ ),
+ default_retryable_errors: Sequence[type[Exception]] = (
+ DeadlineExceeded,
+ ServiceUnavailable,
+ ),
+ ):
+ """Initialize a Table instance
+
+
+
+ Args:
+ instance_id: The Bigtable instance ID to associate with this client.
+ instance_id is combined with the client's project to fully
+ specify the instance
+ table_id: The ID of the table. table_id is combined with the
+ instance_id and the client's project to fully specify the table
+ app_profile_id: The app profile to associate with requests.
+ https://cloud.google.com/bigtable/docs/app-profiles
+ default_read_rows_operation_timeout: The default timeout for read rows
+ operations, in seconds. If not set, defaults to 600 seconds (10 minutes)
+ default_read_rows_attempt_timeout: The default timeout for individual
+ read rows rpc requests, in seconds. If not set, defaults to 20 seconds
+ default_mutate_rows_operation_timeout: The default timeout for mutate rows
+ operations, in seconds. If not set, defaults to 600 seconds (10 minutes)
+ default_mutate_rows_attempt_timeout: The default timeout for individual
+ mutate rows rpc requests, in seconds. If not set, defaults to 60 seconds
+ default_operation_timeout: The default timeout for all other operations, in
+ seconds. If not set, defaults to 60 seconds
+ default_attempt_timeout: The default timeout for all other individual rpc
+ requests, in seconds. If not set, defaults to 20 seconds
+ default_read_rows_retryable_errors: a list of errors that will be retried
+ if encountered during read_rows and related operations.
+ Defaults to 4 (DeadlineExceeded), 14 (ServiceUnavailable), and 10 (Aborted)
+ default_mutate_rows_retryable_errors: a list of errors that will be retried
+ if encountered during mutate_rows and related operations.
+ Defaults to 4 (DeadlineExceeded) and 14 (ServiceUnavailable)
+ default_retryable_errors: a list of errors that will be retried if
+ encountered during all other operations.
+ Defaults to 4 (DeadlineExceeded) and 14 (ServiceUnavailable)
+ Raises:
+ None"""
+ _validate_timeouts(
+ default_operation_timeout, default_attempt_timeout, allow_none=True
+ )
+ _validate_timeouts(
+ default_read_rows_operation_timeout,
+ default_read_rows_attempt_timeout,
+ allow_none=True,
+ )
+ _validate_timeouts(
+ default_mutate_rows_operation_timeout,
+ default_mutate_rows_attempt_timeout,
+ allow_none=True,
+ )
+ self.client = client
+ self.instance_id = instance_id
+ self.instance_name = self.client._gapic_client.instance_path(
+ self.client.project, instance_id
+ )
+ self.table_id = table_id
+ self.table_name = self.client._gapic_client.table_path(
+ self.client.project, instance_id, table_id
+ )
+ self.app_profile_id: str | None = app_profile_id
+ self.default_operation_timeout: float = default_operation_timeout
+ self.default_attempt_timeout: float | None = default_attempt_timeout
+ self.default_read_rows_operation_timeout: float = (
+ default_read_rows_operation_timeout
+ )
+ self.default_read_rows_attempt_timeout: float | None = (
+ default_read_rows_attempt_timeout
+ )
+ self.default_mutate_rows_operation_timeout: float = (
+ default_mutate_rows_operation_timeout
+ )
+ self.default_mutate_rows_attempt_timeout: float | None = (
+ default_mutate_rows_attempt_timeout
+ )
+ self.default_read_rows_retryable_errors: Sequence[type[Exception]] = (
+ default_read_rows_retryable_errors or ()
+ )
+ self.default_mutate_rows_retryable_errors: Sequence[type[Exception]] = (
+ default_mutate_rows_retryable_errors or ()
+ )
+ self.default_retryable_errors: Sequence[type[Exception]] = (
+ default_retryable_errors or ()
+ )
+ self._metrics = BigtableClientSideMetricsController()
+ try:
+ self._register_instance_future = CrossSync._Sync_Impl.create_task(
+ self.client._register_instance,
+ self.instance_id,
+ self.app_profile_id,
+ id(self),
+ sync_executor=self.client._executor,
+ )
+ except RuntimeError as e:
+ raise RuntimeError(
+ f"{self.__class__.__name__} must be created within an async event loop context."
+ ) from e
+
+ @property
+ @abc.abstractmethod
+ def _request_path(self) -> dict[str, str]:
+ """Used to populate table_name or authorized_view_name for rpc requests, depending on the subclass
+
+ Unimplemented in base class"""
+ raise NotImplementedError
+
+ def __str__(self):
+ path_str = list(self._request_path.values())[0] if self._request_path else ""
+ return f"{self.__class__.__name__}<{path_str!r}>"
+
+ def read_rows_stream(
+ self,
+ query: ReadRowsQuery,
+ *,
+ operation_timeout: float | TABLE_DEFAULT = TABLE_DEFAULT.READ_ROWS,
+ attempt_timeout: float | None | TABLE_DEFAULT = TABLE_DEFAULT.READ_ROWS,
+ retryable_errors: Sequence[type[Exception]]
+ | TABLE_DEFAULT = TABLE_DEFAULT.READ_ROWS,
+ ) -> Iterable[Row]:
+ """Read a set of rows from the table, based on the specified query.
+ Returns an iterator to asynchronously stream back row data.
+
+ Failed requests within operation_timeout will be retried based on the
+ retryable_errors list until operation_timeout is reached.
+
+ Args:
+ query: contains details about which rows to return
+ operation_timeout: the time budget for the entire operation, in seconds.
+ Failed requests will be retried within the budget.
+ Defaults to the Table's default_read_rows_operation_timeout
+ attempt_timeout: the time budget for an individual network request, in seconds.
+ If it takes longer than this time to complete, the request will be cancelled with
+ a DeadlineExceeded exception, and a retry will be attempted.
+ Defaults to the Table's default_read_rows_attempt_timeout.
+ If None, defaults to operation_timeout.
+ retryable_errors: a list of errors that will be retried if encountered.
+ Defaults to the Table's default_read_rows_retryable_errors
+ Returns:
+ Iterable[Row]: an asynchronous iterator that yields rows returned by the query
+ Raises:
+ google.api_core.exceptions.DeadlineExceeded: raised after operation timeout
+ will be chained with a RetryExceptionGroup containing GoogleAPIError exceptions
+ from any retries that failed
+ google.api_core.exceptions.GoogleAPIError: raised if the request encounters an unrecoverable error
+ """
+ (operation_timeout, attempt_timeout) = _get_timeouts(
+ operation_timeout, attempt_timeout, self
+ )
+ retryable_excs = _get_retryable_errors(retryable_errors, self)
+ row_merger = CrossSync._Sync_Impl._ReadRowsOperation(
+ query,
+ self,
+ operation_timeout=operation_timeout,
+ attempt_timeout=attempt_timeout,
+ retryable_exceptions=retryable_excs,
+ )
+ return row_merger.start_operation()
+
+ def read_rows(
+ self,
+ query: ReadRowsQuery,
+ *,
+ operation_timeout: float | TABLE_DEFAULT = TABLE_DEFAULT.READ_ROWS,
+ attempt_timeout: float | None | TABLE_DEFAULT = TABLE_DEFAULT.READ_ROWS,
+ retryable_errors: Sequence[type[Exception]]
+ | TABLE_DEFAULT = TABLE_DEFAULT.READ_ROWS,
+ ) -> list[Row]:
+ """Read a set of rows from the table, based on the specified query.
+ Retruns results as a list of Row objects when the request is complete.
+ For streamed results, use read_rows_stream.
+
+ Failed requests within operation_timeout will be retried based on the
+ retryable_errors list until operation_timeout is reached.
+
+ Args:
+ query: contains details about which rows to return
+ operation_timeout: the time budget for the entire operation, in seconds.
+ Failed requests will be retried within the budget.
+ Defaults to the Table's default_read_rows_operation_timeout
+ attempt_timeout: the time budget for an individual network request, in seconds.
+ If it takes longer than this time to complete, the request will be cancelled with
+ a DeadlineExceeded exception, and a retry will be attempted.
+ Defaults to the Table's default_read_rows_attempt_timeout.
+ If None, defaults to operation_timeout.
+ If None, defaults to the Table's default_read_rows_attempt_timeout,
+ or the operation_timeout if that is also None.
+ retryable_errors: a list of errors that will be retried if encountered.
+ Defaults to the Table's default_read_rows_retryable_errors.
+ Returns:
+ list[Row]: a list of Rows returned by the query
+ Raises:
+ google.api_core.exceptions.DeadlineExceeded: raised after operation timeout
+ will be chained with a RetryExceptionGroup containing GoogleAPIError exceptions
+ from any retries that failed
+ google.api_core.exceptions.GoogleAPIError: raised if the request encounters an unrecoverable error
+ """
+ row_generator = self.read_rows_stream(
+ query,
+ operation_timeout=operation_timeout,
+ attempt_timeout=attempt_timeout,
+ retryable_errors=retryable_errors,
+ )
+ return [row for row in row_generator]
+
+ def read_row(
+ self,
+ row_key: str | bytes,
+ *,
+ row_filter: RowFilter | None = None,
+ operation_timeout: float | TABLE_DEFAULT = TABLE_DEFAULT.READ_ROWS,
+ attempt_timeout: float | None | TABLE_DEFAULT = TABLE_DEFAULT.READ_ROWS,
+ retryable_errors: Sequence[type[Exception]]
+ | TABLE_DEFAULT = TABLE_DEFAULT.READ_ROWS,
+ ) -> Row | None:
+ """Read a single row from the table, based on the specified key.
+
+ Failed requests within operation_timeout will be retried based on the
+ retryable_errors list until operation_timeout is reached.
+
+ Args:
+ query: contains details about which rows to return
+ operation_timeout: the time budget for the entire operation, in seconds.
+ Failed requests will be retried within the budget.
+ Defaults to the Table's default_read_rows_operation_timeout
+ attempt_timeout: the time budget for an individual network request, in seconds.
+ If it takes longer than this time to complete, the request will be cancelled with
+ a DeadlineExceeded exception, and a retry will be attempted.
+ Defaults to the Table's default_read_rows_attempt_timeout.
+ If None, defaults to operation_timeout.
+ retryable_errors: a list of errors that will be retried if encountered.
+ Defaults to the Table's default_read_rows_retryable_errors.
+ Returns:
+ Row | None: a Row object if the row exists, otherwise None
+ Raises:
+ google.api_core.exceptions.DeadlineExceeded: raised after operation timeout
+ will be chained with a RetryExceptionGroup containing GoogleAPIError exceptions
+ from any retries that failed
+ google.api_core.exceptions.GoogleAPIError: raised if the request encounters an unrecoverable error
+ """
+ if row_key is None:
+ raise ValueError("row_key must be string or bytes")
+ query = ReadRowsQuery(row_keys=row_key, row_filter=row_filter, limit=1)
+ results = self.read_rows(
+ query,
+ operation_timeout=operation_timeout,
+ attempt_timeout=attempt_timeout,
+ retryable_errors=retryable_errors,
+ )
+ if len(results) == 0:
+ return None
+ return results[0]
+
+ def read_rows_sharded(
+ self,
+ sharded_query: ShardedQuery,
+ *,
+ operation_timeout: float | TABLE_DEFAULT = TABLE_DEFAULT.READ_ROWS,
+ attempt_timeout: float | None | TABLE_DEFAULT = TABLE_DEFAULT.READ_ROWS,
+ retryable_errors: Sequence[type[Exception]]
+ | TABLE_DEFAULT = TABLE_DEFAULT.READ_ROWS,
+ ) -> list[Row]:
+ """Runs a sharded query in parallel, then return the results in a single list.
+ Results will be returned in the order of the input queries.
+
+ This function is intended to be run on the results on a query.shard() call.
+ For example::
+
+ table_shard_keys = await table.sample_row_keys()
+ query = ReadRowsQuery(...)
+ shard_queries = query.shard(table_shard_keys)
+ results = await table.read_rows_sharded(shard_queries)
+
+ Args:
+ sharded_query: a sharded query to execute
+ operation_timeout: the time budget for the entire operation, in seconds.
+ Failed requests will be retried within the budget.
+ Defaults to the Table's default_read_rows_operation_timeout
+ attempt_timeout: the time budget for an individual network request, in seconds.
+ If it takes longer than this time to complete, the request will be cancelled with
+ a DeadlineExceeded exception, and a retry will be attempted.
+ Defaults to the Table's default_read_rows_attempt_timeout.
+ If None, defaults to operation_timeout.
+ retryable_errors: a list of errors that will be retried if encountered.
+ Defaults to the Table's default_read_rows_retryable_errors.
+ Returns:
+ list[Row]: a list of Rows returned by the query
+ Raises:
+ ShardedReadRowsExceptionGroup: if any of the queries failed
+ ValueError: if the query_list is empty"""
+ if not sharded_query:
+ raise ValueError("empty sharded_query")
+ (operation_timeout, attempt_timeout) = _get_timeouts(
+ operation_timeout, attempt_timeout, self
+ )
+ rpc_timeout_generator = _attempt_timeout_generator(
+ operation_timeout, operation_timeout
+ )
+ concurrency_sem = CrossSync._Sync_Impl.Semaphore(_CONCURRENCY_LIMIT)
+
+ def read_rows_with_semaphore(query):
+ with concurrency_sem:
+ shard_timeout = next(rpc_timeout_generator)
+ if shard_timeout <= 0:
+ raise DeadlineExceeded(
+ "Operation timeout exceeded before starting query"
+ )
+ return self.read_rows(
+ query,
+ operation_timeout=shard_timeout,
+ attempt_timeout=min(attempt_timeout, shard_timeout),
+ retryable_errors=retryable_errors,
+ )
+
+ routine_list = [
+ partial(read_rows_with_semaphore, query) for query in sharded_query
+ ]
+ batch_result = CrossSync._Sync_Impl.gather_partials(
+ routine_list, return_exceptions=True, sync_executor=self.client._executor
+ )
+ error_dict = {}
+ shard_idx = 0
+ results_list = []
+ for result in batch_result:
+ if isinstance(result, Exception):
+ error_dict[shard_idx] = result
+ elif isinstance(result, BaseException):
+ raise result
+ else:
+ results_list.extend(result)
+ shard_idx += 1
+ if error_dict:
+ raise ShardedReadRowsExceptionGroup(
+ [
+ FailedQueryShardError(idx, sharded_query[idx], e)
+ for (idx, e) in error_dict.items()
+ ],
+ results_list,
+ len(sharded_query),
+ )
+ return results_list
+
+ def row_exists(
+ self,
+ row_key: str | bytes,
+ *,
+ operation_timeout: float | TABLE_DEFAULT = TABLE_DEFAULT.READ_ROWS,
+ attempt_timeout: float | None | TABLE_DEFAULT = TABLE_DEFAULT.READ_ROWS,
+ retryable_errors: Sequence[type[Exception]]
+ | TABLE_DEFAULT = TABLE_DEFAULT.READ_ROWS,
+ ) -> bool:
+ """Return a boolean indicating whether the specified row exists in the table.
+ uses the filters: chain(limit cells per row = 1, strip value)
+
+ Args:
+ row_key: the key of the row to check
+ operation_timeout: the time budget for the entire operation, in seconds.
+ Failed requests will be retried within the budget.
+ Defaults to the Table's default_read_rows_operation_timeout
+ attempt_timeout: the time budget for an individual network request, in seconds.
+ If it takes longer than this time to complete, the request will be cancelled with
+ a DeadlineExceeded exception, and a retry will be attempted.
+ Defaults to the Table's default_read_rows_attempt_timeout.
+ If None, defaults to operation_timeout.
+ retryable_errors: a list of errors that will be retried if encountered.
+ Defaults to the Table's default_read_rows_retryable_errors.
+ Returns:
+ bool: a bool indicating whether the row exists
+ Raises:
+ google.api_core.exceptions.DeadlineExceeded: raised after operation timeout
+ will be chained with a RetryExceptionGroup containing GoogleAPIError exceptions
+ from any retries that failed
+ google.api_core.exceptions.GoogleAPIError: raised if the request encounters an unrecoverable error
+ """
+ if row_key is None:
+ raise ValueError("row_key must be string or bytes")
+ strip_filter = StripValueTransformerFilter(flag=True)
+ limit_filter = CellsRowLimitFilter(1)
+ chain_filter = RowFilterChain(filters=[limit_filter, strip_filter])
+ query = ReadRowsQuery(row_keys=row_key, limit=1, row_filter=chain_filter)
+ results = self.read_rows(
+ query,
+ operation_timeout=operation_timeout,
+ attempt_timeout=attempt_timeout,
+ retryable_errors=retryable_errors,
+ )
+ return len(results) > 0
+
+ def sample_row_keys(
+ self,
+ *,
+ operation_timeout: float | TABLE_DEFAULT = TABLE_DEFAULT.DEFAULT,
+ attempt_timeout: float | None | TABLE_DEFAULT = TABLE_DEFAULT.DEFAULT,
+ retryable_errors: Sequence[type[Exception]]
+ | TABLE_DEFAULT = TABLE_DEFAULT.DEFAULT,
+ ) -> RowKeySamples:
+ """Return a set of RowKeySamples that delimit contiguous sections of the table of
+ approximately equal size
+
+ RowKeySamples output can be used with ReadRowsQuery.shard() to create a sharded query that
+ can be parallelized across multiple backend nodes read_rows and read_rows_stream
+ requests will call sample_row_keys internally for this purpose when sharding is enabled
+
+ RowKeySamples is simply a type alias for list[tuple[bytes, int]]; a list of
+ row_keys, along with offset positions in the table
+
+ Args:
+ operation_timeout: the time budget for the entire operation, in seconds.
+ Failed requests will be retried within the budget.i
+ Defaults to the Table's default_operation_timeout
+ attempt_timeout: the time budget for an individual network request, in seconds.
+ If it takes longer than this time to complete, the request will be cancelled with
+ a DeadlineExceeded exception, and a retry will be attempted.
+ Defaults to the Table's default_attempt_timeout.
+ If None, defaults to operation_timeout.
+ retryable_errors: a list of errors that will be retried if encountered.
+ Defaults to the Table's default_retryable_errors.
+ Returns:
+ RowKeySamples: a set of RowKeySamples the delimit contiguous sections of the table
+ Raises:
+ google.api_core.exceptions.DeadlineExceeded: raised after operation timeout
+ will be chained with a RetryExceptionGroup containing GoogleAPIError exceptions
+ from any retries that failed
+ google.api_core.exceptions.GoogleAPIError: raised if the request encounters an unrecoverable error
+ """
+ (operation_timeout, attempt_timeout) = _get_timeouts(
+ operation_timeout, attempt_timeout, self
+ )
+ attempt_timeout_gen = _attempt_timeout_generator(
+ attempt_timeout, operation_timeout
+ )
+ retryable_excs = _get_retryable_errors(retryable_errors, self)
+ predicate = retries.if_exception_type(*retryable_excs)
+ sleep_generator = retries.exponential_sleep_generator(0.01, 2, 60)
+
+ def execute_rpc():
+ results = self.client._gapic_client.sample_row_keys(
+ request=SampleRowKeysRequest(
+ app_profile_id=self.app_profile_id, **self._request_path
+ ),
+ timeout=next(attempt_timeout_gen),
+ retry=None,
+ )
+ return [(s.row_key, s.offset_bytes) for s in results]
+
+ return CrossSync._Sync_Impl.retry_target(
+ execute_rpc,
+ predicate,
+ sleep_generator,
+ operation_timeout,
+ exception_factory=_retry_exception_factory,
+ )
+
+ def mutations_batcher(
+ self,
+ *,
+ flush_interval: float | None = 5,
+ flush_limit_mutation_count: int | None = 1000,
+ flush_limit_bytes: int = 20 * _MB_SIZE,
+ flow_control_max_mutation_count: int = 100000,
+ flow_control_max_bytes: int = 100 * _MB_SIZE,
+ batch_operation_timeout: float | TABLE_DEFAULT = TABLE_DEFAULT.MUTATE_ROWS,
+ batch_attempt_timeout: float | None | TABLE_DEFAULT = TABLE_DEFAULT.MUTATE_ROWS,
+ batch_retryable_errors: Sequence[type[Exception]]
+ | TABLE_DEFAULT = TABLE_DEFAULT.MUTATE_ROWS,
+ ) -> "MutationsBatcher":
+ """Returns a new mutations batcher instance.
+
+ Can be used to iteratively add mutations that are flushed as a group,
+ to avoid excess network calls
+
+ Args:
+ flush_interval: Automatically flush every flush_interval seconds. If None,
+ a table default will be used
+ flush_limit_mutation_count: Flush immediately after flush_limit_mutation_count
+ mutations are added across all entries. If None, this limit is ignored.
+ flush_limit_bytes: Flush immediately after flush_limit_bytes bytes are added.
+ flow_control_max_mutation_count: Maximum number of inflight mutations.
+ flow_control_max_bytes: Maximum number of inflight bytes.
+ batch_operation_timeout: timeout for each mutate_rows operation, in seconds.
+ Defaults to the Table's default_mutate_rows_operation_timeout
+ batch_attempt_timeout: timeout for each individual request, in seconds.
+ Defaults to the Table's default_mutate_rows_attempt_timeout.
+ If None, defaults to batch_operation_timeout.
+ batch_retryable_errors: a list of errors that will be retried if encountered.
+ Defaults to the Table's default_mutate_rows_retryable_errors.
+ Returns:
+ MutationsBatcher: a MutationsBatcher context manager that can batch requests
+ """
+ return CrossSync._Sync_Impl.MutationsBatcher(
+ self,
+ flush_interval=flush_interval,
+ flush_limit_mutation_count=flush_limit_mutation_count,
+ flush_limit_bytes=flush_limit_bytes,
+ flow_control_max_mutation_count=flow_control_max_mutation_count,
+ flow_control_max_bytes=flow_control_max_bytes,
+ batch_operation_timeout=batch_operation_timeout,
+ batch_attempt_timeout=batch_attempt_timeout,
+ batch_retryable_errors=batch_retryable_errors,
+ )
+
+ def mutate_row(
+ self,
+ row_key: str | bytes,
+ mutations: list[Mutation] | Mutation,
+ *,
+ operation_timeout: float | TABLE_DEFAULT = TABLE_DEFAULT.DEFAULT,
+ attempt_timeout: float | None | TABLE_DEFAULT = TABLE_DEFAULT.DEFAULT,
+ retryable_errors: Sequence[type[Exception]]
+ | TABLE_DEFAULT = TABLE_DEFAULT.DEFAULT,
+ ):
+ """Mutates a row atomically.
+
+ Cells already present in the row are left unchanged unless explicitly changed
+ by ``mutation``.
+
+ Idempotent operations (i.e, all mutations have an explicit timestamp) will be
+ retried on server failure. Non-idempotent operations will not.
+
+ Args:
+ row_key: the row to apply mutations to
+ mutations: the set of mutations to apply to the row
+ operation_timeout: the time budget for the entire operation, in seconds.
+ Failed requests will be retried within the budget.
+ Defaults to the Table's default_operation_timeout
+ attempt_timeout: the time budget for an individual network request, in seconds.
+ If it takes longer than this time to complete, the request will be cancelled with
+ a DeadlineExceeded exception, and a retry will be attempted.
+ Defaults to the Table's default_attempt_timeout.
+ If None, defaults to operation_timeout.
+ retryable_errors: a list of errors that will be retried if encountered.
+ Only idempotent mutations will be retried. Defaults to the Table's
+ default_retryable_errors.
+ Raises:
+ google.api_core.exceptions.DeadlineExceeded: raised after operation timeout
+ will be chained with a RetryExceptionGroup containing all
+ GoogleAPIError exceptions from any retries that failed
+ google.api_core.exceptions.GoogleAPIError: raised on non-idempotent operations that cannot be
+ safely retried.
+ ValueError: if invalid arguments are provided"""
+ (operation_timeout, attempt_timeout) = _get_timeouts(
+ operation_timeout, attempt_timeout, self
+ )
+ if not mutations:
+ raise ValueError("No mutations provided")
+ mutations_list = mutations if isinstance(mutations, list) else [mutations]
+ if all((mutation.is_idempotent() for mutation in mutations_list)):
+ predicate = retries.if_exception_type(
+ *_get_retryable_errors(retryable_errors, self)
+ )
+ else:
+ predicate = retries.if_exception_type()
+ sleep_generator = retries.exponential_sleep_generator(0.01, 2, 60)
+ target = partial(
+ self.client._gapic_client.mutate_row,
+ request=MutateRowRequest(
+ row_key=row_key.encode("utf-8")
+ if isinstance(row_key, str)
+ else row_key,
+ mutations=[mutation._to_pb() for mutation in mutations_list],
+ app_profile_id=self.app_profile_id,
+ **self._request_path,
+ ),
+ timeout=attempt_timeout,
+ retry=None,
+ )
+ return CrossSync._Sync_Impl.retry_target(
+ target,
+ predicate,
+ sleep_generator,
+ operation_timeout,
+ exception_factory=_retry_exception_factory,
+ )
+
+ def bulk_mutate_rows(
+ self,
+ mutation_entries: list[RowMutationEntry],
+ *,
+ operation_timeout: float | TABLE_DEFAULT = TABLE_DEFAULT.MUTATE_ROWS,
+ attempt_timeout: float | None | TABLE_DEFAULT = TABLE_DEFAULT.MUTATE_ROWS,
+ retryable_errors: Sequence[type[Exception]]
+ | TABLE_DEFAULT = TABLE_DEFAULT.MUTATE_ROWS,
+ ):
+ """Applies mutations for multiple rows in a single batched request.
+
+ Each individual RowMutationEntry is applied atomically, but separate entries
+ may be applied in arbitrary order (even for entries targetting the same row)
+ In total, the row_mutations can contain at most 100000 individual mutations
+ across all entries
+
+ Idempotent entries (i.e., entries with mutations with explicit timestamps)
+ will be retried on failure. Non-idempotent will not, and will reported in a
+ raised exception group
+
+ Args:
+ mutation_entries: the batches of mutations to apply
+ Each entry will be applied atomically, but entries will be applied
+ in arbitrary order
+ operation_timeout: the time budget for the entire operation, in seconds.
+ Failed requests will be retried within the budget.
+ Defaults to the Table's default_mutate_rows_operation_timeout
+ attempt_timeout: the time budget for an individual network request, in seconds.
+ If it takes longer than this time to complete, the request will be cancelled with
+ a DeadlineExceeded exception, and a retry will be attempted.
+ Defaults to the Table's default_mutate_rows_attempt_timeout.
+ If None, defaults to operation_timeout.
+ retryable_errors: a list of errors that will be retried if encountered.
+ Defaults to the Table's default_mutate_rows_retryable_errors
+ Raises:
+ MutationsExceptionGroup: if one or more mutations fails
+ Contains details about any failed entries in .exceptions
+ ValueError: if invalid arguments are provided"""
+ (operation_timeout, attempt_timeout) = _get_timeouts(
+ operation_timeout, attempt_timeout, self
+ )
+ retryable_excs = _get_retryable_errors(retryable_errors, self)
+ operation = CrossSync._Sync_Impl._MutateRowsOperation(
+ self.client._gapic_client,
+ self,
+ mutation_entries,
+ operation_timeout,
+ attempt_timeout,
+ retryable_exceptions=retryable_excs,
+ )
+ operation.start()
+
+ def check_and_mutate_row(
+ self,
+ row_key: str | bytes,
+ predicate: RowFilter | None,
+ *,
+ true_case_mutations: Mutation | list[Mutation] | None = None,
+ false_case_mutations: Mutation | list[Mutation] | None = None,
+ operation_timeout: float | TABLE_DEFAULT = TABLE_DEFAULT.DEFAULT,
+ ) -> bool:
+ """Mutates a row atomically based on the output of a predicate filter
+
+ Non-idempotent operation: will not be retried
+
+ Args:
+ row_key: the key of the row to mutate
+ predicate: the filter to be applied to the contents of the specified row.
+ Depending on whether or not any results are yielded,
+ either true_case_mutations or false_case_mutations will be executed.
+ If None, checks that the row contains any values at all.
+ true_case_mutations:
+ Changes to be atomically applied to the specified row if
+ predicate yields at least one cell when
+ applied to row_key. Entries are applied in order,
+ meaning that earlier mutations can be masked by later
+ ones. Must contain at least one entry if
+ false_case_mutations is empty, and at most 100000.
+ false_case_mutations:
+ Changes to be atomically applied to the specified row if
+ predicate_filter does not yield any cells when
+ applied to row_key. Entries are applied in order,
+ meaning that earlier mutations can be masked by later
+ ones. Must contain at least one entry if
+ `true_case_mutations` is empty, and at most 100000.
+ operation_timeout: the time budget for the entire operation, in seconds.
+ Failed requests will not be retried. Defaults to the Table's default_operation_timeout
+ Returns:
+ bool indicating whether the predicate was true or false
+ Raises:
+ google.api_core.exceptions.GoogleAPIError: exceptions from grpc call"""
+ (operation_timeout, _) = _get_timeouts(operation_timeout, None, self)
+ if true_case_mutations is not None and (
+ not isinstance(true_case_mutations, list)
+ ):
+ true_case_mutations = [true_case_mutations]
+ true_case_list = [m._to_pb() for m in true_case_mutations or []]
+ if false_case_mutations is not None and (
+ not isinstance(false_case_mutations, list)
+ ):
+ false_case_mutations = [false_case_mutations]
+ false_case_list = [m._to_pb() for m in false_case_mutations or []]
+ result = self.client._gapic_client.check_and_mutate_row(
+ request=CheckAndMutateRowRequest(
+ true_mutations=true_case_list,
+ false_mutations=false_case_list,
+ predicate_filter=predicate._to_pb() if predicate is not None else None,
+ row_key=row_key.encode("utf-8")
+ if isinstance(row_key, str)
+ else row_key,
+ app_profile_id=self.app_profile_id,
+ **self._request_path,
+ ),
+ timeout=operation_timeout,
+ retry=None,
+ )
+ return result.predicate_matched
+
+ def read_modify_write_row(
+ self,
+ row_key: str | bytes,
+ rules: ReadModifyWriteRule | list[ReadModifyWriteRule],
+ *,
+ operation_timeout: float | TABLE_DEFAULT = TABLE_DEFAULT.DEFAULT,
+ ) -> Row:
+ """Reads and modifies a row atomically according to input ReadModifyWriteRules,
+ and returns the contents of all modified cells
+
+ The new value for the timestamp is the greater of the existing timestamp or
+ the current server time.
+
+ Non-idempotent operation: will not be retried
+
+ Args:
+ row_key: the key of the row to apply read/modify/write rules to
+ rules: A rule or set of rules to apply to the row.
+ Rules are applied in order, meaning that earlier rules will affect the
+ results of later ones.
+ operation_timeout: the time budget for the entire operation, in seconds.
+ Failed requests will not be retried.
+ Defaults to the Table's default_operation_timeout.
+ Returns:
+ Row: a Row containing cell data that was modified as part of the operation
+ Raises:
+ google.api_core.exceptions.GoogleAPIError: exceptions from grpc call
+ ValueError: if invalid arguments are provided"""
+ (operation_timeout, _) = _get_timeouts(operation_timeout, None, self)
+ if operation_timeout <= 0:
+ raise ValueError("operation_timeout must be greater than 0")
+ if rules is not None and (not isinstance(rules, list)):
+ rules = [rules]
+ if not rules:
+ raise ValueError("rules must contain at least one item")
+ result = self.client._gapic_client.read_modify_write_row(
+ request=ReadModifyWriteRowRequest(
+ rules=[rule._to_pb() for rule in rules],
+ row_key=row_key.encode("utf-8")
+ if isinstance(row_key, str)
+ else row_key,
+ app_profile_id=self.app_profile_id,
+ **self._request_path,
+ ),
+ timeout=operation_timeout,
+ retry=None,
+ )
+ return Row._from_pb(result.row)
+
+ def close(self):
+ """Called to close the Table instance and release any resources held by it."""
+ self._metrics.close()
+ if self._register_instance_future:
+ self._register_instance_future.cancel()
+ self.client._remove_instance_registration(
+ self.instance_id, self.app_profile_id, id(self)
+ )
+
+ def __enter__(self):
+ """Implement async context manager protocol
+
+ Ensure registration task has time to run, so that
+ grpc channels will be warmed for the specified instance"""
+ if self._register_instance_future:
+ self._register_instance_future
+ return self
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ """Implement async context manager protocol
+
+ Unregister this instance with the client, so that
+ grpc channels will no longer be warmed"""
+ self.close()
+
+
+@CrossSync._Sync_Impl.add_mapping_decorator("Table")
+class Table(_DataApiTarget):
+ """
+ Main Data API surface for interacting with a Bigtable table.
+
+ Table object maintains table_id, and app_profile_id context, and passes them with
+ each call
+ """
+
+ @property
+ def _request_path(self) -> dict[str, str]:
+ return {"table_name": self.table_name}
+
+
+@CrossSync._Sync_Impl.add_mapping_decorator("AuthorizedView")
+class AuthorizedView(_DataApiTarget):
+ """
+ Provides access to an authorized view of a table.
+
+ An authorized view is a subset of a table that you configure to include specific table data.
+ Then you grant access to the authorized view separately from access to the table.
+
+ AuthorizedView object maintains table_id, app_profile_id, and authorized_view_id context,
+ and passed them with each call
+ """
+
+ def __init__(
+ self,
+ client,
+ instance_id,
+ table_id,
+ authorized_view_id,
+ app_profile_id: str | None = None,
+ **kwargs,
+ ):
+ """Initialize an AuthorizedView instance
+
+
+
+ Args:
+ instance_id: The Bigtable instance ID to associate with this client.
+ instance_id is combined with the client's project to fully
+ specify the instance
+ table_id: The ID of the table. table_id is combined with the
+ instance_id and the client's project to fully specify the table
+ authorized_view_id: The id for the authorized view to use for requests
+ app_profile_id: The app profile to associate with requests.
+ https://cloud.google.com/bigtable/docs/app-profiles
+ default_read_rows_operation_timeout: The default timeout for read rows
+ operations, in seconds. If not set, defaults to 600 seconds (10 minutes)
+ default_read_rows_attempt_timeout: The default timeout for individual
+ read rows rpc requests, in seconds. If not set, defaults to 20 seconds
+ default_mutate_rows_operation_timeout: The default timeout for mutate rows
+ operations, in seconds. If not set, defaults to 600 seconds (10 minutes)
+ default_mutate_rows_attempt_timeout: The default timeout for individual
+ mutate rows rpc requests, in seconds. If not set, defaults to 60 seconds
+ default_operation_timeout: The default timeout for all other operations, in
+ seconds. If not set, defaults to 60 seconds
+ default_attempt_timeout: The default timeout for all other individual rpc
+ requests, in seconds. If not set, defaults to 20 seconds
+ default_read_rows_retryable_errors: a list of errors that will be retried
+ if encountered during read_rows and related operations.
+ Defaults to 4 (DeadlineExceeded), 14 (ServiceUnavailable), and 10 (Aborted)
+ default_mutate_rows_retryable_errors: a list of errors that will be retried
+ if encountered during mutate_rows and related operations.
+ Defaults to 4 (DeadlineExceeded) and 14 (ServiceUnavailable)
+ default_retryable_errors: a list of errors that will be retried if
+ encountered during all other operations.
+ Defaults to 4 (DeadlineExceeded) and 14 (ServiceUnavailable)
+ Raises:
+ None"""
+ super().__init__(client, instance_id, table_id, app_profile_id, **kwargs)
+ self.authorized_view_id = authorized_view_id
+ self.authorized_view_name: str = self.client._gapic_client.authorized_view_path(
+ self.client.project, instance_id, table_id, authorized_view_id
+ )
+
+ @property
+ def _request_path(self) -> dict[str, str]:
+ return {"authorized_view_name": self.authorized_view_name}
diff --git a/google/cloud/bigtable/data/_sync_autogen/metrics_interceptor.py b/google/cloud/bigtable/data/_sync_autogen/metrics_interceptor.py
new file mode 100644
index 000000000..c5a59787c
--- /dev/null
+++ b/google/cloud/bigtable/data/_sync_autogen/metrics_interceptor.py
@@ -0,0 +1,126 @@
+# Copyright 2025 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.
+
+# This file is automatically generated by CrossSync. Do not edit manually.
+
+from __future__ import annotations
+from typing import Sequence
+import time
+from functools import wraps
+from google.cloud.bigtable.data._metrics.data_model import ActiveOperationMetric
+from google.cloud.bigtable.data._metrics.data_model import OperationState
+from google.cloud.bigtable.data._metrics.data_model import OperationType
+from grpc import UnaryUnaryClientInterceptor
+from grpc import UnaryStreamClientInterceptor
+
+
+def _with_active_operation(func):
+ """Decorator for interceptor methods to extract the active operation associated with the
+ in-scope contextvars, and pass it to the decorated function."""
+
+ @wraps(func)
+ def wrapper(self, continuation, client_call_details, request):
+ operation: ActiveOperationMetric | None = ActiveOperationMetric.from_context()
+ if operation:
+ if (
+ operation.state == OperationState.CREATED
+ or operation.state == OperationState.BETWEEN_ATTEMPTS
+ ):
+ operation.start_attempt()
+ return func(self, operation, continuation, client_call_details, request)
+ else:
+ return continuation(client_call_details, request)
+
+ return wrapper
+
+
+def _get_metadata(source) -> dict[str, str | bytes] | None:
+ """Helper to extract metadata from a call or RpcError"""
+ try:
+ metadata: Sequence[tuple[str, str | bytes]]
+ metadata = source.trailing_metadata() + source.initial_metadata()
+ return {k: v for (k, v) in metadata}
+ except Exception:
+ return None
+
+
+class BigtableMetricsInterceptor(
+ UnaryUnaryClientInterceptor, UnaryStreamClientInterceptor
+):
+ """
+ An async gRPC interceptor to add client metadata and print server metadata.
+ """
+
+ @_with_active_operation
+ def intercept_unary_unary(
+ self, operation, continuation, client_call_details, request
+ ):
+ """Interceptor for unary rpcs:
+ - MutateRow
+ - CheckAndMutateRow
+ - ReadModifyWriteRow"""
+ metadata = None
+ try:
+ call = continuation(client_call_details, request)
+ metadata = _get_metadata(call)
+ return call
+ except Exception as rpc_error:
+ metadata = _get_metadata(rpc_error)
+ raise rpc_error
+ finally:
+ if metadata is not None:
+ operation.add_response_metadata(metadata)
+
+ @_with_active_operation
+ def intercept_unary_stream(
+ self, operation, continuation, client_call_details, request
+ ):
+ """Interceptor for streaming rpcs:
+ - ReadRows
+ - MutateRows
+ - SampleRowKeys"""
+ try:
+ return self._streaming_generator_wrapper(
+ operation, continuation(client_call_details, request)
+ )
+ except Exception as rpc_error:
+ metadata = _get_metadata(rpc_error)
+ if metadata is not None:
+ operation.add_response_metadata(metadata)
+ raise rpc_error
+
+ @staticmethod
+ def _streaming_generator_wrapper(operation, call):
+ """Wrapped generator to be returned by intercept_unary_stream."""
+ has_first_response = (
+ operation.first_response_latency_ns is not None
+ or operation.op_type != OperationType.READ_ROWS
+ )
+ encountered_exc = None
+ try:
+ for response in call:
+ if not has_first_response:
+ operation.first_response_latency_ns = (
+ time.monotonic_ns() - operation.start_time_ns
+ )
+ has_first_response = True
+ yield response
+ except Exception as e:
+ encountered_exc = e
+ raise
+ finally:
+ if call is not None:
+ metadata = _get_metadata(encountered_exc or call)
+ if metadata is not None:
+ operation.add_response_metadata(metadata)
diff --git a/google/cloud/bigtable/data/_sync_autogen/mutations_batcher.py b/google/cloud/bigtable/data/_sync_autogen/mutations_batcher.py
new file mode 100644
index 000000000..84f0ba8c0
--- /dev/null
+++ b/google/cloud/bigtable/data/_sync_autogen/mutations_batcher.py
@@ -0,0 +1,451 @@
+# Copyright 2024 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.
+#
+
+# This file is automatically generated by CrossSync. Do not edit manually.
+
+from __future__ import annotations
+from typing import Sequence, TYPE_CHECKING, cast
+import atexit
+import warnings
+from collections import deque
+import concurrent.futures
+from google.cloud.bigtable.data.exceptions import MutationsExceptionGroup
+from google.cloud.bigtable.data.exceptions import FailedMutationEntryError
+from google.cloud.bigtable.data._helpers import _get_retryable_errors
+from google.cloud.bigtable.data._helpers import _get_timeouts
+from google.cloud.bigtable.data._helpers import TABLE_DEFAULT
+from google.cloud.bigtable.data.mutations import _MUTATE_ROWS_REQUEST_MUTATION_LIMIT
+from google.cloud.bigtable.data.mutations import Mutation
+from google.cloud.bigtable.data._cross_sync import CrossSync
+
+if TYPE_CHECKING:
+ from google.cloud.bigtable.data.mutations import RowMutationEntry
+ from google.cloud.bigtable.data._sync_autogen.client import (
+ _DataApiTarget as TargetType,
+ )
+_MB_SIZE = 1024 * 1024
+
+
+@CrossSync._Sync_Impl.add_mapping_decorator("_FlowControl")
+class _FlowControl:
+ """
+ Manages flow control for batched mutations. Mutations are registered against
+ the FlowControl object before being sent, which will block if size or count
+ limits have reached capacity. As mutations completed, they are removed from
+ the FlowControl object, which will notify any blocked requests that there
+ is additional capacity.
+
+ Flow limits are not hard limits. If a single mutation exceeds the configured
+ limits, it will be allowed as a single batch when the capacity is available.
+
+ Args:
+ max_mutation_count: maximum number of mutations to send in a single rpc.
+ This corresponds to individual mutations in a single RowMutationEntry.
+ max_mutation_bytes: maximum number of bytes to send in a single rpc.
+ Raises:
+ ValueError: if max_mutation_count or max_mutation_bytes is less than 0
+ """
+
+ def __init__(self, max_mutation_count: int, max_mutation_bytes: int):
+ self._max_mutation_count = max_mutation_count
+ self._max_mutation_bytes = max_mutation_bytes
+ if self._max_mutation_count < 1:
+ raise ValueError("max_mutation_count must be greater than 0")
+ if self._max_mutation_bytes < 1:
+ raise ValueError("max_mutation_bytes must be greater than 0")
+ self._capacity_condition = CrossSync._Sync_Impl.Condition()
+ self._in_flight_mutation_count = 0
+ self._in_flight_mutation_bytes = 0
+
+ def _has_capacity(self, additional_count: int, additional_size: int) -> bool:
+ """Checks if there is capacity to send a new entry with the given size and count
+
+ FlowControl limits are not hard limits. If a single mutation exceeds
+ the configured flow limits, it will be sent in a single batch when
+ previous batches have completed.
+
+ Args:
+ additional_count: number of mutations in the pending entry
+ additional_size: size of the pending entry
+ Returns:
+ bool: True if there is capacity to send the pending entry, False otherwise
+ """
+ acceptable_size = max(self._max_mutation_bytes, additional_size)
+ acceptable_count = max(self._max_mutation_count, additional_count)
+ new_size = self._in_flight_mutation_bytes + additional_size
+ new_count = self._in_flight_mutation_count + additional_count
+ return new_size <= acceptable_size and new_count <= acceptable_count
+
+ def remove_from_flow(
+ self, mutations: RowMutationEntry | list[RowMutationEntry]
+ ) -> None:
+ """Removes mutations from flow control. This method should be called once
+ for each mutation that was sent to add_to_flow, after the corresponding
+ operation is complete.
+
+ Args:
+ mutations: mutation or list of mutations to remove from flow control"""
+ if not isinstance(mutations, list):
+ mutations = [mutations]
+ total_count = sum((len(entry.mutations) for entry in mutations))
+ total_size = sum((entry.size() for entry in mutations))
+ self._in_flight_mutation_count -= total_count
+ self._in_flight_mutation_bytes -= total_size
+ with self._capacity_condition:
+ self._capacity_condition.notify_all()
+
+ def add_to_flow(self, mutations: RowMutationEntry | list[RowMutationEntry]):
+ """Generator function that registers mutations with flow control. As mutations
+ are accepted into the flow control, they are yielded back to the caller,
+ to be sent in a batch. If the flow control is at capacity, the generator
+ will block until there is capacity available.
+
+ Args:
+ mutations: list mutations to break up into batches
+ Yields:
+ list[RowMutationEntry]:
+ list of mutations that have reserved space in the flow control.
+ Each batch contains at least one mutation."""
+ if not isinstance(mutations, list):
+ mutations = [mutations]
+ start_idx = 0
+ end_idx = 0
+ while end_idx < len(mutations):
+ start_idx = end_idx
+ batch_mutation_count = 0
+ with self._capacity_condition:
+ while end_idx < len(mutations):
+ next_entry = mutations[end_idx]
+ next_size = next_entry.size()
+ next_count = len(next_entry.mutations)
+ if (
+ self._has_capacity(next_count, next_size)
+ and batch_mutation_count + next_count
+ <= _MUTATE_ROWS_REQUEST_MUTATION_LIMIT
+ ):
+ end_idx += 1
+ batch_mutation_count += next_count
+ self._in_flight_mutation_bytes += next_size
+ self._in_flight_mutation_count += next_count
+ elif start_idx != end_idx:
+ break
+ else:
+ self._capacity_condition.wait_for(
+ lambda: self._has_capacity(next_count, next_size)
+ )
+ yield mutations[start_idx:end_idx]
+
+
+class MutationsBatcher:
+ """
+ Allows users to send batches using context manager API.
+
+ Runs mutate_row, mutate_rows, and check_and_mutate_row internally, combining
+ to use as few network requests as required
+
+ Will automatically flush the batcher:
+ - every flush_interval seconds
+ - after queue size reaches flush_limit_mutation_count
+ - after queue reaches flush_limit_bytes
+ - when batcher is closed or destroyed
+
+ Args:
+ table: table or autrhorized_view used to preform rpc calls
+ flush_interval: Automatically flush every flush_interval seconds.
+ If None, no time-based flushing is performed.
+ flush_limit_mutation_count: Flush immediately after flush_limit_mutation_count
+ mutations are added across all entries. If None, this limit is ignored.
+ flush_limit_bytes: Flush immediately after flush_limit_bytes bytes are added.
+ flow_control_max_mutation_count: Maximum number of inflight mutations.
+ flow_control_max_bytes: Maximum number of inflight bytes.
+ batch_operation_timeout: timeout for each mutate_rows operation, in seconds.
+ If TABLE_DEFAULT, defaults to the Table's default_mutate_rows_operation_timeout.
+ batch_attempt_timeout: timeout for each individual request, in seconds.
+ If TABLE_DEFAULT, defaults to the Table's default_mutate_rows_attempt_timeout.
+ If None, defaults to batch_operation_timeout.
+ batch_retryable_errors: a list of errors that will be retried if encountered.
+ Defaults to the Table's default_mutate_rows_retryable_errors.
+ """
+
+ def __init__(
+ self,
+ table: TargetType,
+ *,
+ flush_interval: float | None = 5,
+ flush_limit_mutation_count: int | None = 1000,
+ flush_limit_bytes: int = 20 * _MB_SIZE,
+ flow_control_max_mutation_count: int = 100000,
+ flow_control_max_bytes: int = 100 * _MB_SIZE,
+ batch_operation_timeout: float | TABLE_DEFAULT = TABLE_DEFAULT.MUTATE_ROWS,
+ batch_attempt_timeout: float | None | TABLE_DEFAULT = TABLE_DEFAULT.MUTATE_ROWS,
+ batch_retryable_errors: Sequence[type[Exception]]
+ | TABLE_DEFAULT = TABLE_DEFAULT.MUTATE_ROWS,
+ ):
+ (self._operation_timeout, self._attempt_timeout) = _get_timeouts(
+ batch_operation_timeout, batch_attempt_timeout, table
+ )
+ self._retryable_errors: list[type[Exception]] = _get_retryable_errors(
+ batch_retryable_errors, table
+ )
+ self._closed = CrossSync._Sync_Impl.Event()
+ self._target = table
+ self._staged_entries: list[RowMutationEntry] = []
+ (self._staged_count, self._staged_bytes) = (0, 0)
+ self._flow_control = CrossSync._Sync_Impl._FlowControl(
+ flow_control_max_mutation_count, flow_control_max_bytes
+ )
+ self._flush_limit_bytes = flush_limit_bytes
+ self._flush_limit_count = (
+ flush_limit_mutation_count
+ if flush_limit_mutation_count is not None
+ else float("inf")
+ )
+ self._sync_rpc_executor = (
+ concurrent.futures.ThreadPoolExecutor(max_workers=8)
+ if not CrossSync._Sync_Impl.is_async
+ else None
+ )
+ self._sync_flush_executor = (
+ concurrent.futures.ThreadPoolExecutor(max_workers=4)
+ if not CrossSync._Sync_Impl.is_async
+ else None
+ )
+ self._flush_timer = CrossSync._Sync_Impl.create_task(
+ self._timer_routine, flush_interval, sync_executor=self._sync_flush_executor
+ )
+ self._flush_jobs: set[CrossSync._Sync_Impl.Future[None]] = set()
+ self._entries_processed_since_last_raise: int = 0
+ self._exceptions_since_last_raise: int = 0
+ self._exception_list_limit: int = 10
+ self._oldest_exceptions: list[Exception] = []
+ self._newest_exceptions: deque[Exception] = deque(
+ maxlen=self._exception_list_limit
+ )
+ atexit.register(self._on_exit)
+
+ def _timer_routine(self, interval: float | None) -> None:
+ """Set up a background task to flush the batcher every interval seconds
+
+ If interval is None, an empty future is returned
+
+ Args:
+ flush_interval: Automatically flush every flush_interval seconds.
+ If None, no time-based flushing is performed."""
+ if not interval or interval <= 0:
+ return None
+ while not self._closed.is_set():
+ CrossSync._Sync_Impl.event_wait(
+ self._closed, timeout=interval, async_break_early=False
+ )
+ if not self._closed.is_set() and self._staged_entries:
+ self._schedule_flush()
+
+ def append(self, mutation_entry: RowMutationEntry):
+ """Add a new set of mutations to the internal queue
+
+ Args:
+ mutation_entry: new entry to add to flush queue
+ Raises:
+ RuntimeError: if batcher is closed
+ ValueError: if an invalid mutation type is added"""
+ if self._closed.is_set():
+ raise RuntimeError("Cannot append to closed MutationsBatcher")
+ if isinstance(cast(Mutation, mutation_entry), Mutation):
+ raise ValueError(
+ f"invalid mutation type: {type(mutation_entry).__name__}. Only RowMutationEntry objects are supported by batcher"
+ )
+ self._staged_entries.append(mutation_entry)
+ self._staged_count += len(mutation_entry.mutations)
+ self._staged_bytes += mutation_entry.size()
+ if (
+ self._staged_count >= self._flush_limit_count
+ or self._staged_bytes >= self._flush_limit_bytes
+ ):
+ self._schedule_flush()
+ CrossSync._Sync_Impl.yield_to_event_loop()
+
+ def _schedule_flush(self) -> CrossSync._Sync_Impl.Future[None] | None:
+ """Update the flush task to include the latest staged entries
+
+ Returns:
+ Future[None] | None:
+ future representing the background task, if started"""
+ if self._staged_entries:
+ (entries, self._staged_entries) = (self._staged_entries, [])
+ (self._staged_count, self._staged_bytes) = (0, 0)
+ new_task = CrossSync._Sync_Impl.create_task(
+ self._flush_internal, entries, sync_executor=self._sync_flush_executor
+ )
+ if not new_task.done():
+ self._flush_jobs.add(new_task)
+ new_task.add_done_callback(self._flush_jobs.remove)
+ return new_task
+ return None
+
+ def _flush_internal(self, new_entries: list[RowMutationEntry]):
+ """Flushes a set of mutations to the server, and updates internal state
+
+ Args:
+ new_entries list of RowMutationEntry objects to flush"""
+ in_process_requests: list[
+ CrossSync._Sync_Impl.Future[list[FailedMutationEntryError]]
+ ] = []
+ for batch in self._flow_control.add_to_flow(new_entries):
+ batch_task = CrossSync._Sync_Impl.create_task(
+ self._execute_mutate_rows, batch, sync_executor=self._sync_rpc_executor
+ )
+ in_process_requests.append(batch_task)
+ found_exceptions = self._wait_for_batch_results(*in_process_requests)
+ self._entries_processed_since_last_raise += len(new_entries)
+ self._add_exceptions(found_exceptions)
+
+ def _execute_mutate_rows(
+ self, batch: list[RowMutationEntry]
+ ) -> list[FailedMutationEntryError]:
+ """Helper to execute mutation operation on a batch
+
+ Args:
+ batch: list of RowMutationEntry objects to send to server
+ timeout: timeout in seconds. Used as operation_timeout and attempt_timeout.
+ If not given, will use table defaults
+ Returns:
+ list[FailedMutationEntryError]:
+ list of FailedMutationEntryError objects for mutations that failed.
+ FailedMutationEntryError objects will not contain index information"""
+ try:
+ operation = CrossSync._Sync_Impl._MutateRowsOperation(
+ self._target.client._gapic_client,
+ self._target,
+ batch,
+ operation_timeout=self._operation_timeout,
+ attempt_timeout=self._attempt_timeout,
+ retryable_exceptions=self._retryable_errors,
+ )
+ operation.start()
+ except MutationsExceptionGroup as e:
+ for subexc in e.exceptions:
+ subexc.index = None
+ return list(e.exceptions)
+ finally:
+ self._flow_control.remove_from_flow(batch)
+ return []
+
+ def _add_exceptions(self, excs: list[Exception]):
+ """Add new list of exceptions to internal store. To avoid unbounded memory,
+ the batcher will store the first and last _exception_list_limit exceptions,
+ and discard any in between.
+
+ Args:
+ excs: list of exceptions to add to the internal store"""
+ self._exceptions_since_last_raise += len(excs)
+ if excs and len(self._oldest_exceptions) < self._exception_list_limit:
+ addition_count = self._exception_list_limit - len(self._oldest_exceptions)
+ self._oldest_exceptions.extend(excs[:addition_count])
+ excs = excs[addition_count:]
+ if excs:
+ self._newest_exceptions.extend(excs[-self._exception_list_limit :])
+
+ def _raise_exceptions(self):
+ """Raise any unreported exceptions from background flush operations
+
+ Raises:
+ MutationsExceptionGroup: exception group with all unreported exceptions"""
+ if self._oldest_exceptions or self._newest_exceptions:
+ (oldest, self._oldest_exceptions) = (self._oldest_exceptions, [])
+ newest = list(self._newest_exceptions)
+ self._newest_exceptions.clear()
+ (entry_count, self._entries_processed_since_last_raise) = (
+ self._entries_processed_since_last_raise,
+ 0,
+ )
+ (exc_count, self._exceptions_since_last_raise) = (
+ self._exceptions_since_last_raise,
+ 0,
+ )
+ raise MutationsExceptionGroup.from_truncated_lists(
+ first_list=oldest,
+ last_list=newest,
+ total_excs=exc_count,
+ entry_count=entry_count,
+ )
+
+ def __enter__(self):
+ """Allow use of context manager API"""
+ return self
+
+ def __exit__(self, exc_type, exc, tb):
+ """Allow use of context manager API.
+
+ Flushes the batcher and cleans up resources."""
+ self.close()
+
+ @property
+ def closed(self) -> bool:
+ """Returns:
+ - True if the batcher is closed, False otherwise"""
+ return self._closed.is_set()
+
+ def close(self):
+ """Flush queue and clean up resources"""
+ self._closed.set()
+ self._flush_timer.cancel()
+ self._schedule_flush()
+ if self._sync_flush_executor:
+ with self._sync_flush_executor:
+ self._sync_flush_executor.shutdown(wait=True)
+ if self._sync_rpc_executor:
+ with self._sync_rpc_executor:
+ self._sync_rpc_executor.shutdown(wait=True)
+ CrossSync._Sync_Impl.wait([*self._flush_jobs, self._flush_timer])
+ atexit.unregister(self._on_exit)
+ self._raise_exceptions()
+
+ def _on_exit(self):
+ """Called when program is exited. Raises warning if unflushed mutations remain"""
+ if not self._closed.is_set() and self._staged_entries:
+ warnings.warn(
+ f"MutationsBatcher for target {self._target!r} was not closed. {len(self._staged_entries)} Unflushed mutations will not be sent to the server."
+ )
+
+ @staticmethod
+ def _wait_for_batch_results(
+ *tasks: CrossSync._Sync_Impl.Future[list[FailedMutationEntryError]]
+ | CrossSync._Sync_Impl.Future[None],
+ ) -> list[Exception]:
+ """Takes in a list of futures representing _execute_mutate_rows tasks,
+ waits for them to complete, and returns a list of errors encountered.
+
+ Args:
+ *tasks: futures representing _execute_mutate_rows or _flush_internal tasks
+ Returns:
+ list[Exception]:
+ list of Exceptions encountered by any of the tasks. Errors are expected
+ to be FailedMutationEntryError, representing a failed mutation operation.
+ If a task fails with a different exception, it will be included in the
+ output list. Successful tasks will not be represented in the output list.
+ """
+ if not tasks:
+ return []
+ exceptions: list[Exception] = []
+ for task in tasks:
+ try:
+ exc_list = task.result()
+ if exc_list:
+ for exc in exc_list:
+ exc.index = None
+ exceptions.extend(exc_list)
+ except Exception as e:
+ exceptions.append(e)
+ return exceptions
diff --git a/google/cloud/bigtable/data/exceptions.py b/google/cloud/bigtable/data/exceptions.py
new file mode 100644
index 000000000..b19e0e5ea
--- /dev/null
+++ b/google/cloud/bigtable/data/exceptions.py
@@ -0,0 +1,343 @@
+# Copyright 2023 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.
+#
+from __future__ import annotations
+
+import sys
+
+from typing import Any, TYPE_CHECKING
+
+from google.api_core import exceptions as core_exceptions
+from google.cloud.bigtable.data.row import Row
+
+is_311_plus = sys.version_info >= (3, 11)
+
+if TYPE_CHECKING:
+ from google.cloud.bigtable.data.mutations import RowMutationEntry
+ from google.cloud.bigtable.data.read_rows_query import ReadRowsQuery
+
+
+class InvalidChunk(core_exceptions.GoogleAPICallError):
+ """Exception raised to invalid chunk data from back-end."""
+
+
+class _RowSetComplete(Exception):
+ """
+ Internal exception for _ReadRowsOperation
+ Raised in revise_request_rowset when there are no rows left to process when starting a retry attempt
+ """
+
+ pass
+
+
+class _ResetRow(Exception): # noqa: F811
+ """
+ Internal exception for _ReadRowsOperation
+
+ Denotes that the server sent a reset_row marker, telling the client to drop
+ all previous chunks for row_key and re-read from the beginning.
+
+ Args:
+ chunk: the reset_row chunk
+ """
+
+ def __init__(self, chunk):
+ self.chunk = chunk
+
+
+class _MutateRowsIncomplete(RuntimeError):
+ """
+ Exception raised when a mutate_rows call has unfinished work.
+ """
+
+ pass
+
+
+class _BigtableExceptionGroup(ExceptionGroup if is_311_plus else Exception): # type: ignore # noqa: F821
+ """
+ Represents one or more exceptions that occur during a bulk Bigtable operation
+
+ In Python 3.11+, this is an unmodified exception group. In < 3.10, it is a
+ custom exception with some exception group functionality backported, but does
+ Not implement the full API
+ """
+
+ def __init__(self, message, excs):
+ if is_311_plus:
+ super().__init__(message, excs)
+ else:
+ if len(excs) == 0:
+ raise ValueError("exceptions must be a non-empty sequence")
+ self.exceptions = tuple(excs)
+ # simulate an exception group in Python < 3.11 by adding exception info
+ # to the message
+ first_line = "--+---------------- 1 ----------------"
+ last_line = "+------------------------------------"
+ message_parts = [message + "\n" + first_line]
+ # print error info for each exception in the group
+ for idx, e in enumerate(excs[:15]):
+ # apply index header
+ if idx != 0:
+ message_parts.append(
+ f"+---------------- {str(idx + 1).rjust(2)} ----------------"
+ )
+ cause = e.__cause__
+ # if this exception was had a cause, print the cause first
+ # used to display root causes of FailedMutationEntryError and FailedQueryShardError
+ # format matches the error output of Python 3.11+
+ if cause is not None:
+ message_parts.extend(
+ f"| {type(cause).__name__}: {cause}".splitlines()
+ )
+ message_parts.append("| ")
+ message_parts.append(
+ "| The above exception was the direct cause of the following exception:"
+ )
+ message_parts.append("| ")
+ # attach error message for this sub-exception
+ # if the subexception is also a _BigtableExceptionGroup,
+ # error messages will be nested
+ message_parts.extend(f"| {type(e).__name__}: {e}".splitlines())
+ # truncate the message if there are more than 15 exceptions
+ if len(excs) > 15:
+ message_parts.append("+---------------- ... ---------------")
+ message_parts.append(f"| and {len(excs) - 15} more")
+ if last_line not in message_parts[-1]:
+ # in the case of nested _BigtableExceptionGroups, the last line
+ # does not need to be added, since one was added by the final sub-exception
+ message_parts.append(last_line)
+ super().__init__("\n ".join(message_parts))
+
+ def __new__(cls, message, excs):
+ if is_311_plus:
+ return super().__new__(cls, message, excs)
+ else:
+ return super().__new__(cls)
+
+ def __str__(self):
+ if is_311_plus:
+ # don't return built-in sub-exception message
+ return self.args[0]
+ return super().__str__()
+
+ def __repr__(self):
+ """
+ repr representation should strip out sub-exception details
+ """
+ if is_311_plus:
+ return super().__repr__()
+ message = self.args[0].split("\n")[0]
+ return f"{self.__class__.__name__}({message!r}, {self.exceptions!r})"
+
+
+class MutationsExceptionGroup(_BigtableExceptionGroup):
+ """
+ Represents one or more exceptions that occur during a bulk mutation operation
+
+ Exceptions will typically be of type FailedMutationEntryError, but other exceptions may
+ be included if they are raised during the mutation operation
+ """
+
+ @staticmethod
+ def _format_message(
+ excs: list[Exception], total_entries: int, exc_count: int | None = None
+ ) -> str:
+ """
+ Format a message for the exception group
+
+ Args:
+ excs: the exceptions in the group
+ total_entries: the total number of entries attempted, successful or not
+ exc_count: the number of exceptions associated with the request
+ if None, this will be len(excs)
+ Returns:
+ str: the formatted message
+ """
+ exc_count = exc_count if exc_count is not None else len(excs)
+ entry_str = "entry" if exc_count == 1 else "entries"
+ return f"{exc_count} failed {entry_str} from {total_entries} attempted."
+
+ def __init__(
+ self, excs: list[Exception], total_entries: int, message: str | None = None
+ ):
+ """
+ Args:
+ excs: the exceptions in the group
+ total_entries: the total number of entries attempted, successful or not
+ message: the message for the exception group. If None, a default message
+ will be generated
+ """
+ message = (
+ message
+ if message is not None
+ else self._format_message(excs, total_entries)
+ )
+ super().__init__(message, excs)
+ self.total_entries_attempted = total_entries
+
+ def __new__(
+ cls, excs: list[Exception], total_entries: int, message: str | None = None
+ ):
+ """
+ Args:
+ excs: the exceptions in the group
+ total_entries: the total number of entries attempted, successful or not
+ message: the message for the exception group. If None, a default message
+ Returns:
+ MutationsExceptionGroup: the new instance
+ """
+ message = (
+ message if message is not None else cls._format_message(excs, total_entries)
+ )
+ instance = super().__new__(cls, message, excs)
+ instance.total_entries_attempted = total_entries
+ return instance
+
+ @classmethod
+ def from_truncated_lists(
+ cls,
+ first_list: list[Exception],
+ last_list: list[Exception],
+ total_excs: int,
+ entry_count: int,
+ ) -> MutationsExceptionGroup:
+ """
+ Create a MutationsExceptionGroup from two lists of exceptions, representing
+ a larger set that has been truncated. The MutationsExceptionGroup will
+ contain the union of the two lists as sub-exceptions, and the error message
+ describe the number of exceptions that were truncated.
+
+ Args:
+ first_list: the set of oldest exceptions to add to the ExceptionGroup
+ last_list: the set of newest exceptions to add to the ExceptionGroup
+ total_excs: the total number of exceptions associated with the request
+ Should be len(first_list) + len(last_list) + number of dropped exceptions
+ in the middle
+ entry_count: the total number of entries attempted, successful or not
+ Returns:
+ MutationsExceptionGroup: the new instance
+ """
+ first_count, last_count = len(first_list), len(last_list)
+ if first_count + last_count >= total_excs:
+ # no exceptions were dropped
+ return cls(first_list + last_list, entry_count)
+ excs = first_list + last_list
+ truncation_count = total_excs - (first_count + last_count)
+ base_message = cls._format_message(excs, entry_count, total_excs)
+ first_message = f"first {first_count}" if first_count else ""
+ last_message = f"last {last_count}" if last_count else ""
+ conjunction = " and " if first_message and last_message else ""
+ message = f"{base_message} ({first_message}{conjunction}{last_message} attached as sub-exceptions; {truncation_count} truncated)"
+ return cls(excs, entry_count, message)
+
+
+class FailedMutationEntryError(Exception):
+ """
+ Represents a single failed RowMutationEntry in a bulk_mutate_rows request.
+ A collection of FailedMutationEntryErrors will be raised in a MutationsExceptionGroup
+ """
+
+ def __init__(
+ self,
+ failed_idx: int | None,
+ failed_mutation_entry: "RowMutationEntry",
+ cause: Exception,
+ ):
+ idempotent_msg = (
+ "idempotent" if failed_mutation_entry.is_idempotent() else "non-idempotent"
+ )
+ index_msg = f" at index {failed_idx}" if failed_idx is not None else ""
+ message = f"Failed {idempotent_msg} mutation entry{index_msg}"
+ super().__init__(message)
+ self.__cause__ = cause
+ self.index = failed_idx
+ self.entry = failed_mutation_entry
+
+
+class RetryExceptionGroup(_BigtableExceptionGroup):
+ """Represents one or more exceptions that occur during a retryable operation"""
+
+ @staticmethod
+ def _format_message(excs: list[Exception]):
+ if len(excs) == 0:
+ return "No exceptions"
+ plural = "s" if len(excs) > 1 else ""
+ return f"{len(excs)} failed attempt{plural}"
+
+ def __init__(self, excs: list[Exception]):
+ super().__init__(self._format_message(excs), excs)
+
+ def __new__(cls, excs: list[Exception]):
+ return super().__new__(cls, cls._format_message(excs), excs)
+
+
+class ShardedReadRowsExceptionGroup(_BigtableExceptionGroup):
+ """
+ Represents one or more exceptions that occur during a sharded read rows operation
+ """
+
+ @staticmethod
+ def _format_message(excs: list[FailedQueryShardError], total_queries: int):
+ query_str = "query" if total_queries == 1 else "queries"
+ plural_str = "" if len(excs) == 1 else "s"
+ return f"{len(excs)} sub-exception{plural_str} (from {total_queries} {query_str} attempted)"
+
+ def __init__(
+ self,
+ excs: list[FailedQueryShardError],
+ succeeded: list[Row],
+ total_queries: int,
+ ):
+ super().__init__(self._format_message(excs, total_queries), excs)
+ self.successful_rows = succeeded
+
+ def __new__(
+ cls, excs: list[FailedQueryShardError], succeeded: list[Row], total_queries: int
+ ):
+ instance = super().__new__(cls, cls._format_message(excs, total_queries), excs)
+ instance.successful_rows = succeeded
+ return instance
+
+
+class FailedQueryShardError(Exception):
+ """
+ Represents an individual failed query in a sharded read rows operation
+ """
+
+ def __init__(
+ self,
+ failed_index: int,
+ failed_query: "ReadRowsQuery" | dict[str, Any],
+ cause: Exception,
+ ):
+ message = f"Failed query at index {failed_index}"
+ super().__init__(message)
+ self.__cause__ = cause
+ self.index = failed_index
+ self.query = failed_query
+
+
+class InvalidExecuteQueryResponse(core_exceptions.GoogleAPICallError):
+ """Exception raised to invalid query response data from back-end."""
+
+ # Set to internal. This is representative of an internal error.
+ code = 13
+
+
+class ParameterTypeInferenceFailed(ValueError):
+ """Exception raised when query parameter types were not provided and cannot be inferred."""
+
+
+class EarlyMetadataCallError(RuntimeError):
+ """Execption raised when metadata is request from an ExecuteQueryIterator before the first row has been read, or the query has completed"""
diff --git a/google/cloud/bigtable/data/execute_query/__init__.py b/google/cloud/bigtable/data/execute_query/__init__.py
new file mode 100644
index 000000000..029e79b93
--- /dev/null
+++ b/google/cloud/bigtable/data/execute_query/__init__.py
@@ -0,0 +1,43 @@
+# Copyright 2024 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.
+
+from google.cloud.bigtable.data.execute_query._async.execute_query_iterator import (
+ ExecuteQueryIteratorAsync,
+)
+from google.cloud.bigtable.data.execute_query._sync_autogen.execute_query_iterator import (
+ ExecuteQueryIterator,
+)
+from google.cloud.bigtable.data.execute_query.metadata import (
+ Metadata,
+ SqlType,
+)
+from google.cloud.bigtable.data.execute_query.values import (
+ ExecuteQueryValueType,
+ QueryResultRow,
+ Struct,
+)
+from google.cloud.bigtable.data._cross_sync import CrossSync
+
+CrossSync.add_mapping("ExecuteQueryIterator", ExecuteQueryIteratorAsync)
+CrossSync._Sync_Impl.add_mapping("ExecuteQueryIterator", ExecuteQueryIterator)
+
+__all__ = [
+ "ExecuteQueryValueType",
+ "SqlType",
+ "QueryResultRow",
+ "Struct",
+ "Metadata",
+ "ExecuteQueryIteratorAsync",
+ "ExecuteQueryIterator",
+]
diff --git a/google/cloud/bigtable/data/execute_query/_async/__init__.py b/google/cloud/bigtable/data/execute_query/_async/__init__.py
new file mode 100644
index 000000000..6d5e14bcf
--- /dev/null
+++ b/google/cloud/bigtable/data/execute_query/_async/__init__.py
@@ -0,0 +1,13 @@
+# Copyright 2024 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.
diff --git a/google/cloud/bigtable/data/execute_query/_async/execute_query_iterator.py b/google/cloud/bigtable/data/execute_query/_async/execute_query_iterator.py
new file mode 100644
index 000000000..2beda4cd6
--- /dev/null
+++ b/google/cloud/bigtable/data/execute_query/_async/execute_query_iterator.py
@@ -0,0 +1,315 @@
+# Copyright 2024 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.
+
+from __future__ import annotations
+
+from typing import (
+ Any,
+ Dict,
+ Optional,
+ Sequence,
+ Tuple,
+ TYPE_CHECKING,
+)
+from google.api_core import retry as retries
+from google.protobuf.message import Message
+from google.protobuf.internal.enum_type_wrapper import EnumTypeWrapper
+
+from google.cloud.bigtable.data.execute_query._byte_cursor import _ByteCursor
+from google.cloud.bigtable.data._helpers import (
+ _attempt_timeout_generator,
+ _retry_exception_factory,
+)
+from google.cloud.bigtable.data.exceptions import (
+ EarlyMetadataCallError,
+ InvalidExecuteQueryResponse,
+)
+from google.cloud.bigtable.data.execute_query.values import QueryResultRow
+from google.cloud.bigtable.data.execute_query.metadata import Metadata
+from google.cloud.bigtable.data.execute_query._reader import (
+ _QueryResultRowReader,
+ _Reader,
+)
+from google.cloud.bigtable_v2.types.bigtable import (
+ ExecuteQueryRequest as ExecuteQueryRequestPB,
+ ExecuteQueryResponse,
+)
+
+from google.cloud.bigtable.data._cross_sync import CrossSync
+
+if TYPE_CHECKING:
+ if CrossSync.is_async:
+ from google.cloud.bigtable.data import BigtableDataClientAsync as DataClientType
+ else:
+ from google.cloud.bigtable.data import BigtableDataClient as DataClientType
+
+__CROSS_SYNC_OUTPUT__ = (
+ "google.cloud.bigtable.data.execute_query._sync_autogen.execute_query_iterator"
+)
+
+
+def _has_resume_token(response: ExecuteQueryResponse) -> bool:
+ response_pb = response._pb # proto-plus attribute retrieval is slow.
+ if response_pb.HasField("results"):
+ results = response_pb.results
+ return len(results.resume_token) > 0
+ return False
+
+
+@CrossSync.convert_class(sync_name="ExecuteQueryIterator")
+class ExecuteQueryIteratorAsync:
+ @CrossSync.convert(
+ docstring_format_vars={
+ "NO_LOOP": (
+ "RuntimeError: if the instance is not created within an async event loop context.",
+ "None",
+ ),
+ "TASK_OR_THREAD": ("asyncio Tasks", "threads"),
+ }
+ )
+ def __init__(
+ self,
+ client: DataClientType,
+ instance_id: str,
+ app_profile_id: Optional[str],
+ request_body: Dict[str, Any],
+ prepare_metadata: Metadata,
+ attempt_timeout: float | None,
+ operation_timeout: float,
+ req_metadata: Sequence[Tuple[str, str]] = (),
+ retryable_excs: Sequence[type[Exception]] = (),
+ column_info: dict[str, Message | EnumTypeWrapper] | None = None,
+ ) -> None:
+ """
+ Collects responses from ExecuteQuery requests and parses them into QueryResultRows.
+
+ **Please Note** this is not meant to be constructed directly by applications. It should always
+ be created via the client. The constructor is subject to change.
+
+ It is **not thread-safe**. It should not be used by multiple {TASK_OR_THREAD}.
+
+ Args:
+ client: bigtable client
+ instance_id: id of the instance on which the query is executed
+ request_body: dict representing the body of the ExecuteQueryRequest
+ attempt_timeout: the time budget for an individual network request, in seconds.
+ If it takes longer than this time to complete, the request will be cancelled with
+ a DeadlineExceeded exception, and a retry will be attempted.
+ operation_timeout: the time budget for the entire operation, in seconds.
+ Failed requests will be retried within the budget
+ req_metadata: metadata used while sending the gRPC request
+ retryable_excs: a list of errors that will be retried if encountered.
+ column_info: dict with mappings between column names and additional column information
+ for protobuf deserialization.
+ Raises:
+ {NO_LOOP}
+ :class:`ValueError ` as a safeguard if data is processed in an unexpected state
+ """
+ self._table_name = None
+ self._app_profile_id = app_profile_id
+ self._client = client
+ self._instance_id = instance_id
+ self._prepare_metadata: Metadata = prepare_metadata
+ self._final_metadata: Metadata | None = None
+ self._byte_cursor = _ByteCursor()
+ self._reader: _Reader[QueryResultRow] = _QueryResultRowReader()
+ self.has_received_token = False
+ self._result_generator = self._next_impl()
+ self._register_instance_task = None
+ self._fully_consumed = False
+ self._is_closed = False
+ self._request_body = request_body
+ self._attempt_timeout_gen = _attempt_timeout_generator(
+ attempt_timeout, operation_timeout
+ )
+ self._stream = CrossSync.retry_target_stream(
+ self._make_request_with_resume_token,
+ retries.if_exception_type(*retryable_excs),
+ retries.exponential_sleep_generator(0.01, 60, multiplier=2),
+ operation_timeout,
+ exception_factory=_retry_exception_factory,
+ )
+ self._req_metadata = req_metadata
+ self._column_info = column_info
+ try:
+ self._register_instance_task = CrossSync.create_task(
+ self._client._register_instance,
+ self._instance_id,
+ self.app_profile_id,
+ id(self),
+ sync_executor=self._client._executor,
+ )
+ except RuntimeError as e:
+ raise RuntimeError(
+ f"{self.__class__.__name__} must be created within an async event loop context."
+ ) from e
+
+ @property
+ def is_closed(self) -> bool:
+ """Returns True if the iterator is closed, False otherwise."""
+ return self._is_closed
+
+ @property
+ def app_profile_id(self) -> Optional[str]:
+ """Returns the app_profile_id of the iterator."""
+ return self._app_profile_id
+
+ @property
+ def table_name(self) -> Optional[str]:
+ """Returns the table_name of the iterator."""
+ return self._table_name
+
+ @CrossSync.convert
+ async def _make_request_with_resume_token(self):
+ """
+ perfoms the rpc call using the correct resume token.
+ """
+ resume_token = self._byte_cursor.prepare_for_new_request()
+ request = ExecuteQueryRequestPB(
+ {
+ **self._request_body,
+ "resume_token": resume_token,
+ }
+ )
+ return await self._client._gapic_client.execute_query(
+ request,
+ timeout=next(self._attempt_timeout_gen),
+ metadata=self._req_metadata,
+ retry=None,
+ )
+
+ @CrossSync.convert
+ async def _next_impl(self) -> CrossSync.Iterator[QueryResultRow]:
+ """
+ Generator wrapping the response stream which parses the stream results
+ and returns full `QueryResultRow`s.
+ """
+ try:
+ async for response in self._stream:
+ try:
+ # we've received a resume token, so we can finalize the metadata
+ if self._final_metadata is None and _has_resume_token(response):
+ self._finalize_metadata()
+
+ batches_to_parse = self._byte_cursor.consume(response)
+ if not batches_to_parse:
+ continue
+ # metadata must be set at this point since there must be a resume_token
+ # for byte_cursor to yield data
+ if not self.metadata:
+ raise ValueError(
+ "Error parsing response before finalizing metadata"
+ )
+ results = self._reader.consume(
+ batches_to_parse, self.metadata, self._column_info
+ )
+ if results is None:
+ continue
+
+ except ValueError as e:
+ raise InvalidExecuteQueryResponse(
+ "Invalid ExecuteQuery response received"
+ ) from e
+
+ for result in results:
+ yield result
+ # this means the stream has finished with no responses. In that case we know the
+ # latest_prepare_reponses was used successfully so we can finalize the metadata
+ if self._final_metadata is None:
+ self._finalize_metadata()
+ self._fully_consumed = True
+ finally:
+ self._close_internal()
+
+ @CrossSync.convert(sync_name="__next__", replace_symbols={"__anext__": "__next__"})
+ async def __anext__(self) -> QueryResultRow:
+ """
+ Yields QueryResultRows representing the results of the query.
+
+ :raises: :class:`ValueError ` as a safeguard if data is processed in an unexpected state
+ """
+ if self._is_closed:
+ raise CrossSync.StopIteration
+ return await self._result_generator.__anext__()
+
+ @CrossSync.convert(sync_name="__iter__")
+ def __aiter__(self):
+ return self
+
+ @CrossSync.convert
+ def _finalize_metadata(self) -> None:
+ """
+ Sets _final_metadata to the metadata of the latest prepare_response.
+ The iterator should call this after either the first resume token is received or the
+ stream completes succesfully with no responses.
+
+ This can't be set on init because the metadata will be able to change due to plan refresh.
+ Plan refresh isn't implemented yet, but we want functionality to stay the same when it is.
+
+ For example the following scenario for query "SELECT * FROM table":
+ - Make a request, table has one column family 'cf'
+ - Return an incomplete batch
+ - request fails with transient error
+ - Meanwhile the table has had a second column family added 'cf2'
+ - Retry the request, get an error indicating the `prepared_query` has expired
+ - Refresh the prepared_query and retry the request, the new prepared_query
+ contains both 'cf' & 'cf2'
+ - It sends a new incomplete batch and resets the old outdated batch
+ - It send the next chunk with a checksum and resume_token, closing the batch.
+ In this we need to use the updated schema from the refreshed prepare request.
+ """
+ self._final_metadata = self._prepare_metadata
+
+ @property
+ def metadata(self) -> Metadata:
+ """
+ Returns query metadata from the server or None if the iterator has been closed
+ or if metadata has not been set yet.
+
+ Metadata will not be set until the first row has been yielded or response with no rows
+ completes.
+
+ raises: :class:`EarlyMetadataCallError` when called before the first row has been returned
+ or the iterator has completed with no rows in the response.
+ """
+ if not self._final_metadata:
+ raise EarlyMetadataCallError()
+ return self._final_metadata
+
+ @CrossSync.convert
+ async def close(self) -> None:
+ """
+ Cancel all background tasks. Should be called after all rows were processed.
+
+ Called automatically by iterator
+
+ :raises: :class:`ValueError ` if called in an invalid state
+ """
+ # this doesn't need to be async anymore but we wrap the sync api to avoid a breaking
+ # change
+ self._close_internal()
+
+ def _close_internal(self) -> None:
+ if self._is_closed:
+ return
+ # Throw an error if the iterator has been successfully consumed but there is
+ # still buffered data
+ if self._fully_consumed and not self._byte_cursor.empty():
+ raise ValueError("Unexpected buffered data at end of executeQuery reqest")
+ self._is_closed = True
+ if self._register_instance_task is not None:
+ self._register_instance_task.cancel()
+ self._client._remove_instance_registration(
+ self._instance_id, self.app_profile_id, id(self)
+ )
diff --git a/google/cloud/bigtable/data/execute_query/_byte_cursor.py b/google/cloud/bigtable/data/execute_query/_byte_cursor.py
new file mode 100644
index 000000000..16eacbe9b
--- /dev/null
+++ b/google/cloud/bigtable/data/execute_query/_byte_cursor.py
@@ -0,0 +1,123 @@
+# Copyright 2024 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.
+
+from typing import List, Optional
+
+from google.cloud.bigtable.data.execute_query._checksum import _CRC32C
+from google.cloud.bigtable_v2 import ExecuteQueryResponse
+
+
+class _ByteCursor:
+ """
+ Buffers bytes from `ExecuteQuery` responses until resume_token is received or end-of-stream
+ is reached. :class:`google.cloud.bigtable_v2.types.bigtable.ExecuteQueryResponse` obtained from
+ the server should be passed to the ``consume`` method and its non-None results should be passed
+ to appropriate :class:`google.cloud.bigtable.execute_query_reader._Reader` for parsing gathered
+ bytes.
+
+ This class consumes data obtained externally to be usable in both sync and async clients.
+
+ See :class:`google.cloud.bigtable.execute_query_reader._Reader` for more context.
+ """
+
+ def __init__(self):
+ self._batch_buffer = bytearray()
+ self._batches: List[bytes] = []
+ self._resume_token = None
+
+ def reset(self):
+ self._batch_buffer = bytearray()
+ self._batches = []
+
+ def prepare_for_new_request(self):
+ """
+ Prepares this ``_ByteCursor`` for retrying an ``ExecuteQuery`` request.
+
+ Clears internal buffers of this ``_ByteCursor`` and returns last received
+ ``resume_token`` to be used in retried request.
+
+ This is the only method that returns ``resume_token`` to the user.
+ Returning the token to the user is tightly coupled with clearing internal
+ buffers to prevent accidental retry without clearing the state, what would
+ cause invalid results. ``resume_token`` are not needed in other cases,
+ thus they is no separate getter for it.
+
+ Returns:
+ bytes: Last received resume_token.
+ """
+ # The first response of any retried stream will always contain reset, so
+ # this isn't actually necessary, but we do it for safety
+ self.reset()
+ return self._resume_token
+
+ def empty(self) -> bool:
+ return not self._batch_buffer and not self._batches
+
+ def consume(self, response: ExecuteQueryResponse) -> Optional[List[bytes]]:
+ """
+ Reads results bytes from an ``ExecuteQuery`` response and adds them to a buffer.
+
+ If the response contains a ``resume_token``:
+ - the ``resume_token`` is saved in this ``_ByteCursor``, and
+ - internal buffers are flushed and returned to the caller.
+
+ ``resume_token`` is not available directly, but can be retrieved by calling
+ :meth:`._ByteCursor.prepare_for_new_request` when preparing to retry a request.
+
+ Args:
+ response (google.cloud.bigtable_v2.types.bigtable.ExecuteQueryResponse):
+ Response obtained from the stream.
+
+ Returns:
+ bytes or None: List of bytes if buffers were flushed or None otherwise.
+ Each element in the list represents the bytes of a `ProtoRows` message.
+
+ Raises:
+ ValueError: If provided ``ExecuteQueryResponse`` is not valid
+ or contains bytes representing response of a different kind than previously
+ processed responses.
+ """
+ response_pb = response._pb # proto-plus attribute retrieval is slow.
+
+ if response_pb.HasField("results"):
+ results = response_pb.results
+ if results.reset:
+ self.reset()
+ if results.HasField("proto_rows_batch"):
+ self._batch_buffer.extend(results.proto_rows_batch.batch_data)
+ # Note that 0 is a valid checksum so we must check for field presence
+ if results.HasField("batch_checksum"):
+ expected_checksum = results.batch_checksum
+ checksum = _CRC32C.checksum(self._batch_buffer)
+ if expected_checksum != checksum:
+ raise ValueError(
+ f"Unexpected checksum mismatch. Expected: {expected_checksum}, got: {checksum}"
+ )
+ # We have a complete batch so we move it to batches and reset the
+ # batch_buffer
+ self._batches.append(memoryview(self._batch_buffer))
+ self._batch_buffer = bytearray()
+
+ if results.resume_token:
+ self._resume_token = results.resume_token
+
+ if self._batches:
+ if self._batch_buffer:
+ raise ValueError("Unexpected resume_token without checksum")
+ return_value = self._batches
+ self._batches = []
+ return return_value
+ else:
+ raise ValueError(f"Unexpected ExecuteQueryResponse: {response}")
+ return None
diff --git a/google/cloud/bigtable/data/execute_query/_checksum.py b/google/cloud/bigtable/data/execute_query/_checksum.py
new file mode 100644
index 000000000..b45a164d5
--- /dev/null
+++ b/google/cloud/bigtable/data/execute_query/_checksum.py
@@ -0,0 +1,43 @@
+# -*- coding: utf-8 -*-
+# Copyright 2025 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 warnings
+
+with warnings.catch_warnings(record=True) as import_warning:
+ import google_crc32c # type: ignore
+
+
+class _CRC32C(object):
+ """
+ Wrapper around ``google_crc32c`` library
+ """
+
+ warn_emitted = False
+
+ @classmethod
+ def checksum(cls, val: bytearray) -> int:
+ """
+ Returns the crc32c checksum of the data.
+ """
+ if import_warning and not cls.warn_emitted:
+ cls.warn_emitted = True
+ warnings.warn(
+ "Using pure python implementation of `google-crc32` for ExecuteQuery response "
+ "validation. This is significantly slower than the c extension. If possible, "
+ "run in an environment that supports the c extension.",
+ RuntimeWarning,
+ )
+ memory_view = memoryview(val)
+ return google_crc32c.value(bytes(memory_view))
diff --git a/google/cloud/bigtable/data/execute_query/_parameters_formatting.py b/google/cloud/bigtable/data/execute_query/_parameters_formatting.py
new file mode 100644
index 000000000..ed7e946e8
--- /dev/null
+++ b/google/cloud/bigtable/data/execute_query/_parameters_formatting.py
@@ -0,0 +1,155 @@
+# Copyright 2024 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 datetime
+from typing import Any, Dict, Optional
+
+from google.api_core.datetime_helpers import DatetimeWithNanoseconds
+
+from google.cloud.bigtable.data.exceptions import ParameterTypeInferenceFailed
+from google.cloud.bigtable.data.execute_query.metadata import SqlType
+from google.cloud.bigtable.data.execute_query.values import ExecuteQueryValueType
+from google.cloud.bigtable_v2.types.data import Value
+
+
+def _format_execute_query_params(
+ params: Optional[Dict[str, ExecuteQueryValueType]],
+ parameter_types: Optional[Dict[str, SqlType.Type]],
+) -> Dict[str, Value]:
+ """
+ Takes a dictionary of param_name -> param_value and optionally parameter types.
+ If the parameters types are not provided, this function tries to infer them.
+
+ Args:
+ params (Optional[Dict[str, ExecuteQueryValueType]]): mapping from parameter names
+ like they appear in query (without @ at the beginning) to their values.
+ Only values of type ExecuteQueryValueType are permitted.
+ parameter_types (Optional[Dict[str, SqlType.Type]]): mapping of parameter names
+ to their types.
+
+ Raises:
+ ValueError: raised when parameter types cannot be inferred and were not
+ provided explicitly.
+
+ Returns:
+ dictionary prasable to a protobuf represenging parameters as defined
+ in ExecuteQueryRequest.params
+ """
+ if not params:
+ return {}
+ parameter_types = parameter_types or {}
+
+ result_values = {}
+ for key, value in params.items():
+ user_provided_type = parameter_types.get(key)
+ try:
+ if user_provided_type:
+ if not isinstance(user_provided_type, SqlType.Type):
+ raise ValueError(
+ f"Parameter type for {key} should be provided as an instance of SqlType.Type subclass."
+ )
+ param_type = user_provided_type
+ else:
+ param_type = _detect_type(value)
+
+ value_pb_dict = _convert_value_to_pb_value_dict(value, param_type)
+ except ValueError as err:
+ raise ValueError(f"Error when parsing parameter {key}") from err
+ result_values[key] = value_pb_dict
+
+ return result_values
+
+
+def _to_param_types(
+ params: Optional[Dict[str, ExecuteQueryValueType]],
+ param_types: Optional[Dict[str, SqlType.Type]],
+) -> Dict[str, Dict[str, Any]]:
+ """
+ Takes the params and user supplied types and creates a param_type dict for the PrepareQuery api
+
+ Args:
+ params: Dict of param name to param value
+ param_types: Dict of param name to param type for params with types that cannot be inferred
+
+ Returns:
+ Dict containing the param name and type for each parameter
+ """
+ if params is None:
+ return {}
+ formatted_types = {}
+ for param_key, param_value in params.items():
+ if param_types and param_key in param_types:
+ formatted_types[param_key] = param_types[param_key]._to_type_pb_dict()
+ else:
+ formatted_types[param_key] = _detect_type(param_value)._to_type_pb_dict()
+ return formatted_types
+
+
+def _convert_value_to_pb_value_dict(
+ value: ExecuteQueryValueType, param_type: SqlType.Type
+) -> Any:
+ """
+ Takes a value and converts it to a dictionary parsable to a protobuf.
+
+ Args:
+ value (ExecuteQueryValueType): value
+ param_type (SqlType.Type): object describing which ExecuteQuery type the value represents.
+
+ Returns:
+ dictionary parsable to a protobuf.
+ """
+ # type field will be set only in top-level Value.
+ value_dict = param_type._to_value_pb_dict(value)
+ value_dict["type_"] = param_type._to_type_pb_dict()
+ return value_dict
+
+
+_TYPES_TO_TYPE_DICTS = [
+ (bytes, SqlType.Bytes()),
+ (str, SqlType.String()),
+ (bool, SqlType.Bool()),
+ (int, SqlType.Int64()),
+ (DatetimeWithNanoseconds, SqlType.Timestamp()),
+ (datetime.datetime, SqlType.Timestamp()),
+ (datetime.date, SqlType.Date()),
+]
+
+
+def _detect_type(value: ExecuteQueryValueType) -> SqlType.Type:
+ """
+ Infers the ExecuteQuery type based on value. Raises error if type is amiguous.
+ raises ParameterTypeInferenceFailed if not possible.
+ """
+ if value is None:
+ raise ParameterTypeInferenceFailed(
+ "Cannot infer type of None, please provide the type manually."
+ )
+
+ if isinstance(value, list):
+ raise ParameterTypeInferenceFailed(
+ "Cannot infer type of ARRAY parameters, please provide the type manually."
+ )
+
+ if isinstance(value, float):
+ raise ParameterTypeInferenceFailed(
+ "Cannot infer type of float, must specify either FLOAT32 or FLOAT64 type manually."
+ )
+
+ for field_type, type_dict in _TYPES_TO_TYPE_DICTS:
+ if isinstance(value, field_type):
+ return type_dict
+
+ raise ParameterTypeInferenceFailed(
+ f"Cannot infer type of {type(value).__name__}, please provide the type manually."
+ )
diff --git a/google/cloud/bigtable/data/execute_query/_query_result_parsing_utils.py b/google/cloud/bigtable/data/execute_query/_query_result_parsing_utils.py
new file mode 100644
index 000000000..a43539e55
--- /dev/null
+++ b/google/cloud/bigtable/data/execute_query/_query_result_parsing_utils.py
@@ -0,0 +1,265 @@
+# Copyright 2024 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.
+from __future__ import annotations
+
+from typing import Any, Callable, Dict, Type, Optional, Union
+
+from google.protobuf.message import Message
+from google.protobuf.internal.enum_type_wrapper import EnumTypeWrapper
+from google.cloud.bigtable.data.execute_query.values import Struct
+from google.cloud.bigtable.data.execute_query.metadata import SqlType
+from google.cloud.bigtable_v2 import Value as PBValue
+from google.api_core.datetime_helpers import DatetimeWithNanoseconds
+
+_REQUIRED_PROTO_FIELDS = {
+ SqlType.Bytes: "bytes_value",
+ SqlType.String: "string_value",
+ SqlType.Int64: "int_value",
+ SqlType.Float32: "float_value",
+ SqlType.Float64: "float_value",
+ SqlType.Bool: "bool_value",
+ SqlType.Timestamp: "timestamp_value",
+ SqlType.Date: "date_value",
+ SqlType.Struct: "array_value",
+ SqlType.Array: "array_value",
+ SqlType.Map: "array_value",
+ SqlType.Proto: "bytes_value",
+ SqlType.Enum: "int_value",
+}
+
+
+def _parse_array_type(
+ value: PBValue,
+ metadata_type: SqlType.Array,
+ column_name: str | None,
+ column_info: dict[str, Message | EnumTypeWrapper] | None = None,
+) -> list[Any]:
+ """
+ used for parsing an array represented as a protobuf to a python list.
+ """
+ return list(
+ map(
+ lambda val: _parse_pb_value_to_python_value(
+ val, metadata_type.element_type, column_name, column_info
+ ),
+ value.array_value.values,
+ )
+ )
+
+
+def _parse_map_type(
+ value: PBValue,
+ metadata_type: SqlType.Map,
+ column_name: str | None,
+ column_info: dict[str, Message | EnumTypeWrapper] | None = None,
+) -> dict[Any, Any]:
+ """
+ used for parsing a map represented as a protobuf to a python dict.
+
+ Values of type `Map` are stored in a `Value.array_value` where each entry
+ is another `Value.array_value` with two elements (the key and the value,
+ in that order).
+ Normally encoded Map values won't have repeated keys, however, the client
+ must handle the case in which they do. If the same key appears
+ multiple times, the _last_ value takes precedence.
+ """
+
+ try:
+ return dict(
+ map(
+ lambda map_entry: (
+ _parse_pb_value_to_python_value(
+ map_entry.array_value.values[0],
+ metadata_type.key_type,
+ f"{column_name}.key" if column_name is not None else None,
+ column_info,
+ ),
+ _parse_pb_value_to_python_value(
+ map_entry.array_value.values[1],
+ metadata_type.value_type,
+ f"{column_name}.value" if column_name is not None else None,
+ column_info,
+ ),
+ ),
+ value.array_value.values,
+ )
+ )
+ except IndexError:
+ raise ValueError("Invalid map entry - less or more than two values.")
+
+
+def _parse_struct_type(
+ value: PBValue,
+ metadata_type: SqlType.Struct,
+ column_name: str | None,
+ column_info: dict[str, Message | EnumTypeWrapper] | None = None,
+) -> Struct:
+ """
+ used for parsing a struct represented as a protobuf to a
+ google.cloud.bigtable.data.execute_query.Struct
+ """
+ if len(value.array_value.values) != len(metadata_type.fields):
+ raise ValueError("Mismatched lengths of values and types.")
+
+ struct = Struct()
+ for value, field in zip(value.array_value.values, metadata_type.fields):
+ field_name, field_type = field
+ nested_column_name: str | None
+ if column_name and field_name:
+ # qualify the column name for nested lookups
+ nested_column_name = f"{column_name}.{field_name}"
+ else:
+ nested_column_name = None
+ struct.add_field(
+ field_name,
+ _parse_pb_value_to_python_value(
+ value, field_type, nested_column_name, column_info
+ ),
+ )
+
+ return struct
+
+
+def _parse_timestamp_type(
+ value: PBValue,
+ metadata_type: SqlType.Timestamp,
+ column_name: str | None,
+ column_info: dict[str, Message | EnumTypeWrapper] | None = None,
+) -> DatetimeWithNanoseconds:
+ """
+ used for parsing a timestamp represented as a protobuf to DatetimeWithNanoseconds
+ """
+ return DatetimeWithNanoseconds.from_timestamp_pb(value.timestamp_value)
+
+
+def _parse_proto_type(
+ value: PBValue,
+ metadata_type: SqlType.Proto,
+ column_name: str | None,
+ column_info: dict[str, Message | EnumTypeWrapper] | None = None,
+) -> Message | bytes:
+ """
+ Parses a serialized protobuf message into a Message object using type information
+ provided in column_info.
+
+ Args:
+ value: The value to parse, expected to have a bytes_value attribute.
+ metadata_type: The expected SQL type (Proto).
+ column_name: The name of the column.
+ column_info: (Optional) A dictionary mapping column names to their
+ corresponding Protobuf Message classes. This information is used
+ to deserialize the raw bytes.
+
+ Returns:
+ A deserialized Protobuf Message object if parsing is successful.
+ If the required type information is not found in column_info, the function
+ returns the original serialized data as bytes (value.bytes_value).
+ This fallback ensures that the raw data is still accessible.
+
+ Raises:
+ google.protobuf.message.DecodeError: If `value.bytes_value` cannot be
+ parsed as the Message type specified in `column_info`.
+ """
+ if (
+ column_name is not None
+ and column_info is not None
+ and column_info.get(column_name) is not None
+ ):
+ default_proto_message = column_info.get(column_name)
+ if isinstance(default_proto_message, Message):
+ proto_message = type(default_proto_message)()
+ proto_message.ParseFromString(value.bytes_value)
+ return proto_message
+ return value.bytes_value
+
+
+def _parse_enum_type(
+ value: PBValue,
+ metadata_type: SqlType.Enum,
+ column_name: str | None,
+ column_info: dict[str, Message | EnumTypeWrapper] | None = None,
+) -> int | str:
+ """
+ Parses an integer value into a Protobuf enum name string using type information
+ provided in column_info.
+
+ Args:
+ value: The value to parse, expected to have an int_value attribute.
+ metadata_type: The expected SQL type (Enum).
+ column_name: The name of the column.
+ column_info: (Optional) A dictionary mapping column names to their
+ corresponding Protobuf EnumTypeWrapper objects. This information
+ is used to convert the integer to an enum name.
+
+ Returns:
+ A string representing the name of the enum value if conversion is successful.
+ If conversion fails for any reason, such as the required EnumTypeWrapper
+ not being found in column_info, or if an error occurs during the name lookup
+ (e.g., the integer is not a valid enum value), the function returns the
+ original integer value (value.int_value). This fallback ensures the
+ raw integer representation is still accessible.
+ """
+ if (
+ column_name is not None
+ and column_info is not None
+ and column_info.get(column_name) is not None
+ ):
+ proto_enum = column_info.get(column_name)
+ if isinstance(proto_enum, EnumTypeWrapper):
+ return proto_enum.Name(value.int_value)
+ return value.int_value
+
+
+ParserCallable = Callable[
+ [PBValue, Any, Optional[str], Optional[Dict[str, Union[Message, EnumTypeWrapper]]]],
+ Any,
+]
+
+_TYPE_PARSERS: Dict[Type[SqlType.Type], ParserCallable] = {
+ SqlType.Timestamp: _parse_timestamp_type,
+ SqlType.Struct: _parse_struct_type,
+ SqlType.Array: _parse_array_type,
+ SqlType.Map: _parse_map_type,
+ SqlType.Proto: _parse_proto_type,
+ SqlType.Enum: _parse_enum_type,
+}
+
+
+def _parse_pb_value_to_python_value(
+ value: PBValue,
+ metadata_type: SqlType.Type,
+ column_name: str | None,
+ column_info: dict[str, Message | EnumTypeWrapper] | None = None,
+) -> Any:
+ """
+ used for converting the value represented as a protobufs to a python object.
+ """
+ value_kind = value.WhichOneof("kind")
+ if not value_kind:
+ return None
+
+ kind = type(metadata_type)
+ if not value.HasField(_REQUIRED_PROTO_FIELDS[kind]):
+ raise ValueError(
+ f"{_REQUIRED_PROTO_FIELDS[kind]} field for {kind.__name__} type not found in a Value."
+ )
+
+ if kind in _TYPE_PARSERS:
+ parser = _TYPE_PARSERS[kind]
+ return parser(value, metadata_type, column_name, column_info)
+ elif kind in _REQUIRED_PROTO_FIELDS:
+ field_name = _REQUIRED_PROTO_FIELDS[kind]
+ return getattr(value, field_name)
+ else:
+ raise ValueError(f"Unknown kind {kind}")
diff --git a/google/cloud/bigtable/data/execute_query/_reader.py b/google/cloud/bigtable/data/execute_query/_reader.py
new file mode 100644
index 000000000..467c2030f
--- /dev/null
+++ b/google/cloud/bigtable/data/execute_query/_reader.py
@@ -0,0 +1,142 @@
+# Copyright 2024 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.
+from __future__ import annotations
+
+from typing import (
+ List,
+ TypeVar,
+ Generic,
+ Iterable,
+ Optional,
+ Sequence,
+)
+from abc import ABC, abstractmethod
+from google.protobuf.message import Message
+from google.protobuf.internal.enum_type_wrapper import EnumTypeWrapper
+
+from google.cloud.bigtable_v2 import ProtoRows, Value as PBValue
+
+from google.cloud.bigtable.data.execute_query._query_result_parsing_utils import (
+ _parse_pb_value_to_python_value,
+)
+
+from google.cloud.bigtable.helpers import batched
+
+from google.cloud.bigtable.data.execute_query.values import QueryResultRow
+from google.cloud.bigtable.data.execute_query.metadata import Metadata
+
+
+T = TypeVar("T")
+
+
+class _Reader(ABC, Generic[T]):
+ """
+ An interface for classes that consume and parse bytes returned by ``_ByteCursor``.
+ Parsed bytes should be gathered into bundles (rows or columns) of expected size
+ and converted to an appropriate type ``T`` that will be returned as a semantically
+ meaningful result to the library user by
+ :meth:`google.cloud.bigtable.instance.Instance.execute_query` or
+ :meth:`google.cloud.bigtable.data._async.client.BigtableDataClientAsync.execute_query`
+ methods.
+
+ This class consumes data obtained externally to be usable in both sync and async clients.
+
+ See :class:`google.cloud.bigtable.byte_cursor._ByteCursor` for more context.
+ """
+
+ @abstractmethod
+ def consume(
+ self,
+ batches_to_consume: List[bytes],
+ metadata: Metadata,
+ column_info: dict[str, Message | EnumTypeWrapper] | None = None,
+ ) -> Optional[Iterable[T]]:
+ """This method receives a list of batches of bytes to be parsed as ProtoRows messages.
+ It then uses the metadata to group the values in the parsed messages into rows. Returns
+ None if batches_to_consume is empty
+ Args:
+ bytes_to_consume (bytes): chunk of parsable byte batches received from
+ :meth:`google.cloud.bigtable.byte_cursor._ByteCursor.consume`
+ method.
+ metadata: metadata used to transform values to rows
+ column_info: (Optional) dict with mappings between column names and additional column information
+ for protobuf deserialization.
+
+ Returns:
+ Iterable[T] or None: Iterable if gathered values can form one or more instances of T,
+ or None if there is not enough data to construct at least one instance of T with
+ appropriate number of entries.
+ """
+ raise NotImplementedError
+
+
+class _QueryResultRowReader(_Reader[QueryResultRow]):
+ """
+ A :class:`._Reader` consuming bytes representing
+ :class:`google.cloud.bigtable_v2.types.Type`
+ and producing :class:`google.cloud.bigtable.execute_query.QueryResultRow`.
+
+ Number of entries in each row is determined by number of columns in
+ :class:`google.cloud.bigtable.execute_query.Metadata` obtained from
+ :class:`google.cloud.bigtable.byte_cursor._ByteCursor` passed in the constructor.
+ """
+
+ def _parse_proto_rows(self, bytes_to_parse: bytes) -> Iterable[PBValue]:
+ proto_rows = ProtoRows.pb().FromString(bytes_to_parse)
+ return proto_rows.values
+
+ def _construct_query_result_row(
+ self,
+ values: Sequence[PBValue],
+ metadata: Metadata,
+ column_info: dict[str, Message | EnumTypeWrapper] | None = None,
+ ) -> QueryResultRow:
+ result = QueryResultRow()
+ columns = metadata.columns
+
+ assert len(values) == len(
+ columns
+ ), "This function should be called only when count of values matches count of columns."
+
+ for column, value in zip(columns, values):
+ parsed_value = _parse_pb_value_to_python_value(
+ value, column.column_type, column.column_name, column_info
+ )
+ result.add_field(column.column_name, parsed_value)
+ return result
+
+ def consume(
+ self,
+ batches_to_consume: List[bytes],
+ metadata: Metadata,
+ column_info: dict[str, Message | EnumTypeWrapper] | None = None,
+ ) -> Optional[Iterable[QueryResultRow]]:
+ num_columns = len(metadata.columns)
+ rows = []
+ for batch_bytes in batches_to_consume:
+ values = self._parse_proto_rows(batch_bytes)
+ for row_data in batched(values, n=num_columns):
+ if len(row_data) == num_columns:
+ rows.append(
+ self._construct_query_result_row(
+ row_data, metadata, column_info
+ )
+ )
+ else:
+ raise ValueError(
+ "Unexpected error, recieved bad number of values. "
+ f"Expected {num_columns} got {len(row_data)}."
+ )
+
+ return rows
diff --git a/google/cloud/bigtable/data/execute_query/_sync_autogen/execute_query_iterator.py b/google/cloud/bigtable/data/execute_query/_sync_autogen/execute_query_iterator.py
new file mode 100644
index 000000000..68594d0e8
--- /dev/null
+++ b/google/cloud/bigtable/data/execute_query/_sync_autogen/execute_query_iterator.py
@@ -0,0 +1,259 @@
+# Copyright 2024 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.
+
+
+# This file is automatically generated by CrossSync. Do not edit manually.
+
+from __future__ import annotations
+from typing import Any, Dict, Optional, Sequence, Tuple, TYPE_CHECKING
+from google.api_core import retry as retries
+from google.protobuf.message import Message
+from google.protobuf.internal.enum_type_wrapper import EnumTypeWrapper
+from google.cloud.bigtable.data.execute_query._byte_cursor import _ByteCursor
+from google.cloud.bigtable.data._helpers import (
+ _attempt_timeout_generator,
+ _retry_exception_factory,
+)
+from google.cloud.bigtable.data.exceptions import (
+ EarlyMetadataCallError,
+ InvalidExecuteQueryResponse,
+)
+from google.cloud.bigtable.data.execute_query.values import QueryResultRow
+from google.cloud.bigtable.data.execute_query.metadata import Metadata
+from google.cloud.bigtable.data.execute_query._reader import (
+ _QueryResultRowReader,
+ _Reader,
+)
+from google.cloud.bigtable_v2.types.bigtable import (
+ ExecuteQueryRequest as ExecuteQueryRequestPB,
+ ExecuteQueryResponse,
+)
+from google.cloud.bigtable.data._cross_sync import CrossSync
+
+if TYPE_CHECKING:
+ from google.cloud.bigtable.data import BigtableDataClient as DataClientType
+
+
+def _has_resume_token(response: ExecuteQueryResponse) -> bool:
+ response_pb = response._pb
+ if response_pb.HasField("results"):
+ results = response_pb.results
+ return len(results.resume_token) > 0
+ return False
+
+
+class ExecuteQueryIterator:
+ def __init__(
+ self,
+ client: DataClientType,
+ instance_id: str,
+ app_profile_id: Optional[str],
+ request_body: Dict[str, Any],
+ prepare_metadata: Metadata,
+ attempt_timeout: float | None,
+ operation_timeout: float,
+ req_metadata: Sequence[Tuple[str, str]] = (),
+ retryable_excs: Sequence[type[Exception]] = (),
+ column_info: dict[str, Message | EnumTypeWrapper] | None = None,
+ ) -> None:
+ """Collects responses from ExecuteQuery requests and parses them into QueryResultRows.
+
+ **Please Note** this is not meant to be constructed directly by applications. It should always
+ be created via the client. The constructor is subject to change.
+
+ It is **not thread-safe**. It should not be used by multiple threads.
+
+ Args:
+ client: bigtable client
+ instance_id: id of the instance on which the query is executed
+ request_body: dict representing the body of the ExecuteQueryRequest
+ attempt_timeout: the time budget for an individual network request, in seconds.
+ If it takes longer than this time to complete, the request will be cancelled with
+ a DeadlineExceeded exception, and a retry will be attempted.
+ operation_timeout: the time budget for the entire operation, in seconds.
+ Failed requests will be retried within the budget
+ req_metadata: metadata used while sending the gRPC request
+ retryable_excs: a list of errors that will be retried if encountered.
+ column_info: dict with mappings between column names and additional column information
+ for protobuf deserialization.
+ Raises:
+ None
+ :class:`ValueError ` as a safeguard if data is processed in an unexpected state
+ """
+ self._table_name = None
+ self._app_profile_id = app_profile_id
+ self._client = client
+ self._instance_id = instance_id
+ self._prepare_metadata: Metadata = prepare_metadata
+ self._final_metadata: Metadata | None = None
+ self._byte_cursor = _ByteCursor()
+ self._reader: _Reader[QueryResultRow] = _QueryResultRowReader()
+ self.has_received_token = False
+ self._result_generator = self._next_impl()
+ self._register_instance_task = None
+ self._fully_consumed = False
+ self._is_closed = False
+ self._request_body = request_body
+ self._attempt_timeout_gen = _attempt_timeout_generator(
+ attempt_timeout, operation_timeout
+ )
+ self._stream = CrossSync._Sync_Impl.retry_target_stream(
+ self._make_request_with_resume_token,
+ retries.if_exception_type(*retryable_excs),
+ retries.exponential_sleep_generator(0.01, 60, multiplier=2),
+ operation_timeout,
+ exception_factory=_retry_exception_factory,
+ )
+ self._req_metadata = req_metadata
+ self._column_info = column_info
+ try:
+ self._register_instance_task = CrossSync._Sync_Impl.create_task(
+ self._client._register_instance,
+ self._instance_id,
+ self.app_profile_id,
+ id(self),
+ sync_executor=self._client._executor,
+ )
+ except RuntimeError as e:
+ raise RuntimeError(
+ f"{self.__class__.__name__} must be created within an async event loop context."
+ ) from e
+
+ @property
+ def is_closed(self) -> bool:
+ """Returns True if the iterator is closed, False otherwise."""
+ return self._is_closed
+
+ @property
+ def app_profile_id(self) -> Optional[str]:
+ """Returns the app_profile_id of the iterator."""
+ return self._app_profile_id
+
+ @property
+ def table_name(self) -> Optional[str]:
+ """Returns the table_name of the iterator."""
+ return self._table_name
+
+ def _make_request_with_resume_token(self):
+ """perfoms the rpc call using the correct resume token."""
+ resume_token = self._byte_cursor.prepare_for_new_request()
+ request = ExecuteQueryRequestPB(
+ {**self._request_body, "resume_token": resume_token}
+ )
+ return self._client._gapic_client.execute_query(
+ request,
+ timeout=next(self._attempt_timeout_gen),
+ metadata=self._req_metadata,
+ retry=None,
+ )
+
+ def _next_impl(self) -> CrossSync._Sync_Impl.Iterator[QueryResultRow]:
+ """Generator wrapping the response stream which parses the stream results
+ and returns full `QueryResultRow`s."""
+ try:
+ for response in self._stream:
+ try:
+ if self._final_metadata is None and _has_resume_token(response):
+ self._finalize_metadata()
+ batches_to_parse = self._byte_cursor.consume(response)
+ if not batches_to_parse:
+ continue
+ if not self.metadata:
+ raise ValueError(
+ "Error parsing response before finalizing metadata"
+ )
+ results = self._reader.consume(
+ batches_to_parse, self.metadata, self._column_info
+ )
+ if results is None:
+ continue
+ except ValueError as e:
+ raise InvalidExecuteQueryResponse(
+ "Invalid ExecuteQuery response received"
+ ) from e
+ for result in results:
+ yield result
+ if self._final_metadata is None:
+ self._finalize_metadata()
+ self._fully_consumed = True
+ finally:
+ self._close_internal()
+
+ def __next__(self) -> QueryResultRow:
+ """Yields QueryResultRows representing the results of the query.
+
+ :raises: :class:`ValueError ` as a safeguard if data is processed in an unexpected state
+ """
+ if self._is_closed:
+ raise CrossSync._Sync_Impl.StopIteration
+ return self._result_generator.__next__()
+
+ def __iter__(self):
+ return self
+
+ def _finalize_metadata(self) -> None:
+ """Sets _final_metadata to the metadata of the latest prepare_response.
+ The iterator should call this after either the first resume token is received or the
+ stream completes succesfully with no responses.
+
+ This can't be set on init because the metadata will be able to change due to plan refresh.
+ Plan refresh isn't implemented yet, but we want functionality to stay the same when it is.
+
+ For example the following scenario for query "SELECT * FROM table":
+ - Make a request, table has one column family 'cf'
+ - Return an incomplete batch
+ - request fails with transient error
+ - Meanwhile the table has had a second column family added 'cf2'
+ - Retry the request, get an error indicating the `prepared_query` has expired
+ - Refresh the prepared_query and retry the request, the new prepared_query
+ contains both 'cf' & 'cf2'
+ - It sends a new incomplete batch and resets the old outdated batch
+ - It send the next chunk with a checksum and resume_token, closing the batch.
+ In this we need to use the updated schema from the refreshed prepare request."""
+ self._final_metadata = self._prepare_metadata
+
+ @property
+ def metadata(self) -> Metadata:
+ """Returns query metadata from the server or None if the iterator has been closed
+ or if metadata has not been set yet.
+
+ Metadata will not be set until the first row has been yielded or response with no rows
+ completes.
+
+ raises: :class:`EarlyMetadataCallError` when called before the first row has been returned
+ or the iterator has completed with no rows in the response."""
+ if not self._final_metadata:
+ raise EarlyMetadataCallError()
+ return self._final_metadata
+
+ def close(self) -> None:
+ """Cancel all background tasks. Should be called after all rows were processed.
+
+ Called automatically by iterator
+
+ :raises: :class:`ValueError ` if called in an invalid state
+ """
+ self._close_internal()
+
+ def _close_internal(self) -> None:
+ if self._is_closed:
+ return
+ if self._fully_consumed and (not self._byte_cursor.empty()):
+ raise ValueError("Unexpected buffered data at end of executeQuery reqest")
+ self._is_closed = True
+ if self._register_instance_task is not None:
+ self._register_instance_task.cancel()
+ self._client._remove_instance_registration(
+ self._instance_id, self.app_profile_id, id(self)
+ )
diff --git a/google/cloud/bigtable/data/execute_query/metadata.py b/google/cloud/bigtable/data/execute_query/metadata.py
new file mode 100644
index 000000000..74b6cb836
--- /dev/null
+++ b/google/cloud/bigtable/data/execute_query/metadata.py
@@ -0,0 +1,425 @@
+# Copyright 2024 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.
+
+"""
+This module provides the SqlType class used for specifying types in
+ExecuteQuery and some utilities.
+
+The SqlTypes are used in Metadata returned by the ExecuteQuery operation as well
+as for specifying query parameter types explicitly.
+"""
+
+from collections import defaultdict
+import datetime
+from typing import Any, Dict, List, Optional, Set, Tuple, Type, Union
+
+from google.api_core.datetime_helpers import DatetimeWithNanoseconds
+from google.protobuf import timestamp_pb2 # type: ignore
+from google.type import date_pb2 # type: ignore
+
+from google.cloud.bigtable.data.execute_query.values import _NamedList
+from google.cloud.bigtable_v2 import ResultSetMetadata
+from google.cloud.bigtable_v2 import Type as PBType
+
+
+class SqlType:
+ """
+ Classes denoting types of values returned by Bigtable's ExecuteQuery operation.
+
+ Used in :class:`.Metadata`.
+ """
+
+ class Type:
+ expected_type: Optional[type] = None
+ value_pb_dict_field_name: Optional[str] = None
+ type_field_name: Optional[str] = None
+
+ @classmethod
+ def from_pb_type(cls, pb_type: Optional[PBType] = None):
+ return cls()
+
+ def _to_type_pb_dict(self) -> Dict[str, Any]:
+ if not self.type_field_name:
+ raise NotImplementedError(
+ "Fill in expected_type and value_pb_dict_field_name"
+ )
+
+ return {self.type_field_name: {}}
+
+ def _to_value_pb_dict(self, value: Any) -> Dict[str, Any]:
+ if self.expected_type is None or self.value_pb_dict_field_name is None:
+ raise NotImplementedError(
+ "Fill in expected_type and value_pb_dict_field_name"
+ )
+
+ if value is None:
+ return {}
+
+ if not isinstance(value, self.expected_type):
+ raise ValueError(
+ f"Expected query parameter of type {self.expected_type.__name__}, got {type(value).__name__}"
+ )
+
+ return {self.value_pb_dict_field_name: value}
+
+ def __eq__(self, other):
+ return isinstance(other, type(self))
+
+ def __str__(self) -> str:
+ return self.__class__.__name__
+
+ def __repr__(self) -> str:
+ return self.__str__()
+
+ class Struct(_NamedList[Type], Type):
+ """Struct SQL type."""
+
+ @classmethod
+ def from_pb_type(cls, type_pb: Optional[PBType] = None) -> "SqlType.Struct":
+ if type_pb is None:
+ raise ValueError("missing required argument type_pb")
+ fields: List[Tuple[Optional[str], SqlType.Type]] = []
+ for field in type_pb.struct_type.fields:
+ fields.append((field.field_name, _pb_type_to_metadata_type(field.type)))
+ return cls(fields)
+
+ def _to_value_pb_dict(self, value: Any):
+ raise NotImplementedError("Struct is not supported as a query parameter")
+
+ def _to_type_pb_dict(self) -> Dict[str, Any]:
+ raise NotImplementedError("Struct is not supported as a query parameter")
+
+ def __eq__(self, other: object):
+ # Cannot use super() here - we'd either have to:
+ # - call super() in these base classes, which would in turn call Object.__eq__
+ # to compare objects by identity and return a False, or
+ # - do not call super() in these base classes, which would result in calling only
+ # one of the __eq__ methods (a super() in the base class would be required to call the other one), or
+ # - call super() in only one of the base classes, but that would be error prone and changing
+ # the order of base classes would introduce unexpected behaviour.
+ # we also have to disable mypy because it doesn't see that SqlType.Struct == _NamedList[Type]
+ return SqlType.Type.__eq__(self, other) and _NamedList.__eq__(self, other) # type: ignore
+
+ def __str__(self):
+ return super(_NamedList, self).__str__()
+
+ class Array(Type):
+ """Array SQL type."""
+
+ def __init__(self, element_type: "SqlType.Type"):
+ if isinstance(element_type, SqlType.Array):
+ raise ValueError("Arrays of arrays are not supported.")
+ if isinstance(element_type, SqlType.Map):
+ raise ValueError("Arrays of Maps are not supported.")
+ self._element_type = element_type
+
+ @property
+ def element_type(self):
+ return self._element_type
+
+ @classmethod
+ def from_pb_type(cls, type_pb: Optional[PBType] = None) -> "SqlType.Array":
+ if type_pb is None:
+ raise ValueError("missing required argument type_pb")
+ return cls(_pb_type_to_metadata_type(type_pb.array_type.element_type))
+
+ def _to_value_pb_dict(self, value: Any):
+ if value is None:
+ return {}
+
+ return {
+ "array_value": {
+ "values": [
+ self.element_type._to_value_pb_dict(entry) for entry in value
+ ]
+ }
+ }
+
+ def _to_type_pb_dict(self) -> Dict[str, Any]:
+ return {
+ "array_type": {"element_type": self.element_type._to_type_pb_dict()}
+ }
+
+ def __eq__(self, other):
+ return super().__eq__(other) and self.element_type == other.element_type
+
+ def __str__(self) -> str:
+ return f"{self.__class__.__name__}<{str(self.element_type)}>"
+
+ class Map(Type):
+ """Map SQL type."""
+
+ def __init__(self, key_type: "SqlType.Type", value_type: "SqlType.Type"):
+ self._key_type = key_type
+ self._value_type = value_type
+
+ @property
+ def key_type(self):
+ return self._key_type
+
+ @property
+ def value_type(self):
+ return self._value_type
+
+ @classmethod
+ def from_pb_type(cls, type_pb: Optional[PBType] = None) -> "SqlType.Map":
+ if type_pb is None:
+ raise ValueError("missing required argument type_pb")
+ return cls(
+ _pb_type_to_metadata_type(type_pb.map_type.key_type),
+ _pb_type_to_metadata_type(type_pb.map_type.value_type),
+ )
+
+ def _to_type_pb_dict(self) -> Dict[str, Any]:
+ raise NotImplementedError("Map is not supported as a query parameter")
+
+ def _to_value_pb_dict(self, value: Any):
+ raise NotImplementedError("Map is not supported as a query parameter")
+
+ def __eq__(self, other):
+ return (
+ super().__eq__(other)
+ and self.key_type == other.key_type
+ and self.value_type == other.value_type
+ )
+
+ def __str__(self) -> str:
+ return (
+ f"{self.__class__.__name__}<"
+ f"{str(self._key_type)},{str(self._value_type)}>"
+ )
+
+ class Bytes(Type):
+ """Bytes SQL type."""
+
+ expected_type = bytes
+ value_pb_dict_field_name = "bytes_value"
+ type_field_name = "bytes_type"
+
+ class String(Type):
+ """String SQL type."""
+
+ expected_type = str
+ value_pb_dict_field_name = "string_value"
+ type_field_name = "string_type"
+
+ class Int64(Type):
+ """Int64 SQL type."""
+
+ expected_type = int
+ value_pb_dict_field_name = "int_value"
+ type_field_name = "int64_type"
+
+ class Float64(Type):
+ """Float64 SQL type."""
+
+ expected_type = float
+ value_pb_dict_field_name = "float_value"
+ type_field_name = "float64_type"
+
+ class Float32(Type):
+ """Float32 SQL type."""
+
+ expected_type = float
+ value_pb_dict_field_name = "float_value"
+ type_field_name = "float32_type"
+
+ class Bool(Type):
+ """Bool SQL type."""
+
+ expected_type = bool
+ value_pb_dict_field_name = "bool_value"
+ type_field_name = "bool_type"
+
+ class Timestamp(Type):
+ """
+ Timestamp SQL type.
+
+ Timestamp supports :class:`DatetimeWithNanoseconds` but Bigtable SQL does
+ not currently support nanoseconds precision. We support this for potential
+ compatibility in the future. Nanoseconds are currently ignored.
+ """
+
+ type_field_name = "timestamp_type"
+ expected_types = (
+ datetime.datetime,
+ DatetimeWithNanoseconds,
+ )
+
+ def _to_value_pb_dict(self, value: Any) -> Dict[str, Any]:
+ if value is None:
+ return {}
+
+ if not isinstance(value, self.expected_types):
+ raise ValueError(
+ f"Expected one of {', '.join((_type.__name__ for _type in self.expected_types))}"
+ )
+
+ if isinstance(value, DatetimeWithNanoseconds):
+ return {"timestamp_value": value.timestamp_pb()}
+ else: # value must be an instance of datetime.datetime
+ ts = timestamp_pb2.Timestamp()
+ ts.FromDatetime(value)
+ return {"timestamp_value": ts}
+
+ class Date(Type):
+ """Date SQL type."""
+
+ type_field_name = "date_type"
+ expected_type = datetime.date
+
+ def _to_value_pb_dict(self, value: Any) -> Dict[str, Any]:
+ if value is None:
+ return {}
+
+ if not isinstance(value, self.expected_type):
+ raise ValueError(
+ f"Expected query parameter of type {self.expected_type.__name__}, got {type(value).__name__}"
+ )
+
+ return {
+ "date_value": date_pb2.Date(
+ year=value.year,
+ month=value.month,
+ day=value.day,
+ )
+ }
+
+ class Proto(Type):
+ """Proto SQL type."""
+
+ type_field_name = "proto_type"
+
+ def _to_value_pb_dict(self, value: Any):
+ raise NotImplementedError("Proto is not supported as a query parameter")
+
+ def _to_type_pb_dict(self) -> Dict[str, Any]:
+ raise NotImplementedError("Proto is not supported as a query parameter")
+
+ class Enum(Type):
+ """Enum SQL type."""
+
+ type_field_name = "enum_type"
+
+ def _to_value_pb_dict(self, value: Any):
+ raise NotImplementedError("Enum is not supported as a query parameter")
+
+ def _to_type_pb_dict(self) -> Dict[str, Any]:
+ raise NotImplementedError("Enum is not supported as a query parameter")
+
+
+class Metadata:
+ """
+ Metadata class for the ExecuteQuery operation.
+
+ Args:
+ columns (List[Tuple[Optional[str], SqlType.Type]]): List of column
+ metadata tuples. Each tuple contains the column name and the column
+ type.
+ """
+
+ class Column:
+ def __init__(self, column_name: Optional[str], column_type: SqlType.Type):
+ self._column_name = column_name
+ self._column_type = column_type
+
+ @property
+ def column_name(self) -> Optional[str]:
+ return self._column_name
+
+ @property
+ def column_type(self) -> SqlType.Type:
+ return self._column_type
+
+ @property
+ def columns(self) -> List[Column]:
+ return self._columns
+
+ def __init__(
+ self, columns: Optional[List[Tuple[Optional[str], SqlType.Type]]] = None
+ ):
+ self._columns: List[Metadata.Column] = []
+ self._column_indexes: Dict[str, List[int]] = defaultdict(list)
+ self._duplicate_names: Set[str] = set()
+
+ if columns:
+ for column_name, column_type in columns:
+ if column_name is not None:
+ if column_name in self._column_indexes:
+ self._duplicate_names.add(column_name)
+ self._column_indexes[column_name].append(len(self._columns))
+ self._columns.append(Metadata.Column(column_name, column_type))
+
+ def __getitem__(self, index_or_name: Union[str, int]) -> Column:
+ if isinstance(index_or_name, str):
+ if index_or_name in self._duplicate_names:
+ raise KeyError(
+ f"Ambigious column name: '{index_or_name}', use index instead."
+ f" Field present on indexes {', '.join(map(str, self._column_indexes[index_or_name]))}."
+ )
+ if index_or_name not in self._column_indexes:
+ raise KeyError(f"No such column: {index_or_name}")
+ index = self._column_indexes[index_or_name][0]
+ else:
+ index = index_or_name
+ return self._columns[index]
+
+ def __len__(self):
+ return len(self._columns)
+
+ def __str__(self) -> str:
+ columns_str = ", ".join([str(column) for column in self._columns])
+ return f"{self.__class__.__name__}([{columns_str}])"
+
+ def __repr__(self) -> str:
+ return self.__str__()
+
+
+def _pb_metadata_to_metadata_types(
+ metadata_pb: ResultSetMetadata,
+) -> Metadata:
+ if "proto_schema" in metadata_pb:
+ fields: List[Tuple[Optional[str], SqlType.Type]] = []
+ if not metadata_pb.proto_schema.columns:
+ raise ValueError("Invalid empty ResultSetMetadata received.")
+ for column_metadata in metadata_pb.proto_schema.columns:
+ fields.append(
+ (column_metadata.name, _pb_type_to_metadata_type(column_metadata.type))
+ )
+ return Metadata(fields)
+ raise ValueError("Invalid ResultSetMetadata object received.")
+
+
+_PROTO_TYPE_TO_METADATA_TYPE_FACTORY: Dict[str, Type[SqlType.Type]] = {
+ "bytes_type": SqlType.Bytes,
+ "string_type": SqlType.String,
+ "int64_type": SqlType.Int64,
+ "float32_type": SqlType.Float32,
+ "float64_type": SqlType.Float64,
+ "bool_type": SqlType.Bool,
+ "timestamp_type": SqlType.Timestamp,
+ "date_type": SqlType.Date,
+ "proto_type": SqlType.Proto,
+ "enum_type": SqlType.Enum,
+ "struct_type": SqlType.Struct,
+ "array_type": SqlType.Array,
+ "map_type": SqlType.Map,
+}
+
+
+def _pb_type_to_metadata_type(type_pb: PBType) -> SqlType.Type:
+ kind = PBType.pb(type_pb).WhichOneof("kind")
+ if kind in _PROTO_TYPE_TO_METADATA_TYPE_FACTORY:
+ return _PROTO_TYPE_TO_METADATA_TYPE_FACTORY[kind].from_pb_type(type_pb)
+ raise ValueError(f"Unrecognized response data type: {type_pb}")
diff --git a/google/cloud/bigtable/data/execute_query/values.py b/google/cloud/bigtable/data/execute_query/values.py
new file mode 100644
index 000000000..80a0bff6f
--- /dev/null
+++ b/google/cloud/bigtable/data/execute_query/values.py
@@ -0,0 +1,123 @@
+# Copyright 2024 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.
+
+from collections import defaultdict
+from typing import (
+ Optional,
+ List,
+ Dict,
+ Set,
+ Union,
+ TypeVar,
+ Generic,
+ Tuple,
+ Mapping,
+)
+from google.type import date_pb2 # type: ignore
+from google.api_core.datetime_helpers import DatetimeWithNanoseconds
+
+T = TypeVar("T")
+
+
+class _NamedList(Generic[T]):
+ """
+ A class designed to store a list of elements, which can be accessed by
+ name or index.
+ This class is different from namedtuple, because namedtuple has some
+ restrictions on names of fields and we do not want to have them.
+ """
+
+ _str_cls_name = "_NamedList"
+
+ def __init__(self, fields: Optional[List[Tuple[Optional[str], T]]] = None):
+ self._fields: List[Tuple[Optional[str], T]] = []
+ self._field_indexes: Dict[str, List[int]] = defaultdict(list)
+ self._duplicate_names: Set[str] = set()
+
+ if fields:
+ for field_name, field_type in fields:
+ self.add_field(field_name, field_type)
+
+ def add_field(self, name: Optional[str], value: T):
+ if name:
+ if name in self._field_indexes:
+ self._duplicate_names.add(name)
+ self._field_indexes[name].append(len(self._fields))
+ self._fields.append((name, value))
+
+ @property
+ def fields(self):
+ return self._fields
+
+ def __getitem__(self, index_or_name: Union[str, int]):
+ if isinstance(index_or_name, str):
+ if index_or_name in self._duplicate_names:
+ raise KeyError(
+ f"Ambigious field name: '{index_or_name}', use index instead."
+ f" Field present on indexes {', '.join(map(str, self._field_indexes[index_or_name]))}."
+ )
+ if index_or_name not in self._field_indexes:
+ raise KeyError(f"No such field: {index_or_name}")
+ index = self._field_indexes[index_or_name][0]
+ else:
+ index = index_or_name
+ return self._fields[index][1]
+
+ def __len__(self):
+ return len(self._fields)
+
+ def __eq__(self, other):
+ if not isinstance(other, _NamedList):
+ return False
+
+ return (
+ self._fields == other._fields
+ and self._field_indexes == other._field_indexes
+ )
+
+ def __str__(self) -> str:
+ fields_str = ", ".join([str(field) for field in self._fields])
+ return f"{self.__class__.__name__}([{fields_str}])"
+
+ def __repr__(self) -> str:
+ return self.__str__()
+
+
+ExecuteQueryValueType = Union[
+ int,
+ float,
+ bool,
+ bytes,
+ str,
+ # Note that Bigtable SQL does not currently support nanosecond precision,
+ # only microseconds. We use this for compatibility with potential future
+ # support
+ DatetimeWithNanoseconds,
+ date_pb2.Date,
+ "Struct",
+ List["ExecuteQueryValueType"],
+ Mapping[Union[str, int, bytes], "ExecuteQueryValueType"],
+]
+
+
+class QueryResultRow(_NamedList[ExecuteQueryValueType]):
+ """
+ Represents a single row of the result
+ """
+
+
+class Struct(_NamedList[ExecuteQueryValueType]):
+ """
+ Represents a struct value in the result
+ """
diff --git a/google/cloud/bigtable/data/mutations.py b/google/cloud/bigtable/data/mutations.py
new file mode 100644
index 000000000..f19b1e49e
--- /dev/null
+++ b/google/cloud/bigtable/data/mutations.py
@@ -0,0 +1,457 @@
+# Copyright 2023 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.
+#
+from __future__ import annotations
+from typing import Any
+import time
+from dataclasses import dataclass
+from abc import ABC, abstractmethod
+from sys import getsizeof
+
+import google.cloud.bigtable_v2.types.bigtable as types_pb
+import google.cloud.bigtable_v2.types.data as data_pb
+
+from google.cloud.bigtable.data.read_modify_write_rules import _MAX_INCREMENT_VALUE
+
+
+# special value for SetCell mutation timestamps. If set, server will assign a timestamp
+_SERVER_SIDE_TIMESTAMP = -1
+
+# mutation entries above this should be rejected
+_MUTATE_ROWS_REQUEST_MUTATION_LIMIT = 100_000
+
+
+class Mutation(ABC):
+ """
+ Abstract base class for mutations.
+
+ This class defines the interface for different types of mutations that can be
+ applied to Bigtable rows.
+ """
+
+ @abstractmethod
+ def _to_dict(self) -> dict[str, Any]:
+ """
+ Convert the mutation to a dictionary representation.
+
+ Returns:
+ dict[str, Any]: A dictionary representation of the mutation.
+ """
+ raise NotImplementedError
+
+ def _to_pb(self) -> data_pb.Mutation:
+ """
+ Convert the mutation to a protobuf representation.
+
+ Returns:
+ Mutation: A protobuf representation of the mutation.
+ """
+ return data_pb.Mutation(**self._to_dict())
+
+ def is_idempotent(self) -> bool:
+ """
+ Check if the mutation is idempotent
+
+ Idempotent mutations can be safely retried on failure.
+
+ Returns:
+ bool: True if the mutation is idempotent, False otherwise.
+ """
+ return True
+
+ def __str__(self) -> str:
+ """
+ Return a string representation of the mutation.
+
+ Returns:
+ str: A string representation of the mutation.
+ """
+ return str(self._to_dict())
+
+ def size(self) -> int:
+ """
+ Get the size of the mutation in bytes
+
+ Returns:
+ int: The size of the mutation in bytes.
+ """
+ return getsizeof(self._to_dict())
+
+ @classmethod
+ def _from_dict(cls, input_dict: dict[str, Any]) -> Mutation:
+ """
+ Create a `Mutation` instance from a dictionary representation.
+
+ Args:
+ input_dict: A dictionary representation of the mutation.
+ Returns:
+ Mutation: A Mutation instance created from the dictionary.
+ Raises:
+ ValueError: If the input dictionary is invalid or does not represent a valid mutation type.
+ """
+ instance: Mutation | None = None
+ try:
+ if "set_cell" in input_dict:
+ details = input_dict["set_cell"]
+ instance = SetCell(
+ details["family_name"],
+ details["column_qualifier"],
+ details["value"],
+ details["timestamp_micros"],
+ )
+ elif "delete_from_column" in input_dict:
+ details = input_dict["delete_from_column"]
+ time_range = details.get("time_range", {})
+ start = time_range.get("start_timestamp_micros", None)
+ end = time_range.get("end_timestamp_micros", None)
+ instance = DeleteRangeFromColumn(
+ details["family_name"], details["column_qualifier"], start, end
+ )
+ elif "delete_from_family" in input_dict:
+ details = input_dict["delete_from_family"]
+ instance = DeleteAllFromFamily(details["family_name"])
+ elif "delete_from_row" in input_dict:
+ instance = DeleteAllFromRow()
+ elif "add_to_cell" in input_dict:
+ details = input_dict["add_to_cell"]
+ instance = AddToCell(
+ details["family_name"],
+ details["column_qualifier"]["raw_value"],
+ details["input"]["int_value"],
+ details["timestamp"]["raw_timestamp_micros"],
+ )
+ except KeyError as e:
+ raise ValueError("Invalid mutation dictionary") from e
+ if instance is None:
+ raise ValueError("No valid mutation found")
+ if not issubclass(instance.__class__, cls):
+ raise ValueError("Mutation type mismatch")
+ return instance
+
+
+class SetCell(Mutation):
+ """
+ Mutation to set the value of a cell.
+
+ Args:
+ family: The name of the column family to which the new cell belongs.
+ qualifier: The column qualifier of the new cell.
+ new_value: The value of the new cell.
+ timestamp_micros: The timestamp of the new cell. If `None`,
+ the current timestamp will be used. Timestamps will be sent with
+ millisecond precision. Extra precision will be truncated. If -1, the
+ server will assign a timestamp. Note that `SetCell` mutations with
+ server-side timestamps are non-idempotent operations and will not be retried.
+
+ Raises:
+ TypeError: If `qualifier` is not `bytes` or `str`.
+ TypeError: If `new_value` is not `bytes`, `str`, or `int`.
+ ValueError: If `timestamp_micros` is less than `_SERVER_SIDE_TIMESTAMP`.
+ """
+
+ def __init__(
+ self,
+ family: str,
+ qualifier: bytes | str,
+ new_value: bytes | str | int,
+ timestamp_micros: int | None = None,
+ ):
+ qualifier = qualifier.encode() if isinstance(qualifier, str) else qualifier
+ if not isinstance(qualifier, bytes):
+ raise TypeError("qualifier must be bytes or str")
+ if isinstance(new_value, str):
+ new_value = new_value.encode()
+ elif isinstance(new_value, int):
+ if abs(new_value) > _MAX_INCREMENT_VALUE:
+ raise ValueError(
+ "int values must be between -2**63 and 2**63 (64-bit signed int)"
+ )
+ new_value = new_value.to_bytes(8, "big", signed=True)
+ if not isinstance(new_value, bytes):
+ raise TypeError("new_value must be bytes, str, or int")
+ if timestamp_micros is None:
+ # use current timestamp, with milisecond precision
+ timestamp_micros = time.time_ns() // 1000
+ timestamp_micros = timestamp_micros - (timestamp_micros % 1000)
+ if timestamp_micros < _SERVER_SIDE_TIMESTAMP:
+ raise ValueError(
+ f"timestamp_micros must be positive (or {_SERVER_SIDE_TIMESTAMP} for server-side timestamp)"
+ )
+ self.family = family
+ self.qualifier = qualifier
+ self.new_value = new_value
+ self.timestamp_micros = timestamp_micros
+
+ def _to_dict(self) -> dict[str, Any]:
+ return {
+ "set_cell": {
+ "family_name": self.family,
+ "column_qualifier": self.qualifier,
+ "timestamp_micros": self.timestamp_micros,
+ "value": self.new_value,
+ }
+ }
+
+ def is_idempotent(self) -> bool:
+ return self.timestamp_micros != _SERVER_SIDE_TIMESTAMP
+
+
+@dataclass
+class DeleteRangeFromColumn(Mutation):
+ """
+ Mutation to delete a range of cells from a column.
+
+ Args:
+ family: The name of the column family.
+ qualifier: The column qualifier.
+ start_timestamp_micros: The start timestamp of the range to
+ delete. `None` represents 0. Defaults to `None`.
+ end_timestamp_micros: The end timestamp of the range to
+ delete. `None` represents infinity. Defaults to `None`.
+ Raises:
+ ValueError: If `start_timestamp_micros` is greater than `end_timestamp_micros`.
+ """
+
+ family: str
+ qualifier: bytes
+ # None represents 0
+ start_timestamp_micros: int | None = None
+ # None represents infinity
+ end_timestamp_micros: int | None = None
+
+ def __post_init__(self):
+ if (
+ self.start_timestamp_micros is not None
+ and self.end_timestamp_micros is not None
+ and self.start_timestamp_micros > self.end_timestamp_micros
+ ):
+ raise ValueError("start_timestamp_micros must be <= end_timestamp_micros")
+
+ def _to_dict(self) -> dict[str, Any]:
+ timestamp_range = {}
+ if self.start_timestamp_micros is not None:
+ timestamp_range["start_timestamp_micros"] = self.start_timestamp_micros
+ if self.end_timestamp_micros is not None:
+ timestamp_range["end_timestamp_micros"] = self.end_timestamp_micros
+ return {
+ "delete_from_column": {
+ "family_name": self.family,
+ "column_qualifier": self.qualifier,
+ "time_range": timestamp_range,
+ }
+ }
+
+
+@dataclass
+class DeleteAllFromFamily(Mutation):
+ """
+ Mutation to delete all cells from a column family.
+
+ Args:
+ family_to_delete: The name of the column family to delete.
+ """
+
+ family_to_delete: str
+
+ def _to_dict(self) -> dict[str, Any]:
+ return {
+ "delete_from_family": {
+ "family_name": self.family_to_delete,
+ }
+ }
+
+
+@dataclass
+class DeleteAllFromRow(Mutation):
+ """
+ Mutation to delete all cells from a row.
+ """
+
+ def _to_dict(self) -> dict[str, Any]:
+ return {
+ "delete_from_row": {},
+ }
+
+
+@dataclass
+class AddToCell(Mutation):
+ """
+ Adds an int64 value to an aggregate cell. The column family must be an
+ aggregate family and have an "int64" input type or this mutation will be
+ rejected.
+
+ Note: The timestamp values are in microseconds but must match the
+ granularity of the table (defaults to `MILLIS`). Therefore, the given value
+ must be a multiple of 1000 (millisecond granularity). For example:
+ `1571902339435000`.
+
+ Args:
+ family: The name of the column family to which the cell belongs.
+ qualifier: The column qualifier of the cell.
+ value: The value to be accumulated into the cell.
+ timestamp_micros: The timestamp of the cell. Must be provided for
+ cell aggregation to work correctly.
+
+
+ Raises:
+ TypeError: If `qualifier` is not `bytes` or `str`.
+ TypeError: If `value` is not `int`.
+ TypeError: If `timestamp_micros` is not `int`.
+ ValueError: If `value` is out of bounds for a 64-bit signed int.
+ ValueError: If `timestamp_micros` is less than 0.
+ """
+
+ def __init__(
+ self,
+ family: str,
+ qualifier: bytes | str,
+ value: int,
+ timestamp_micros: int,
+ ):
+ qualifier = qualifier.encode() if isinstance(qualifier, str) else qualifier
+ if not isinstance(qualifier, bytes):
+ raise TypeError("qualifier must be bytes or str")
+ if not isinstance(value, int):
+ raise TypeError("value must be int")
+ if not isinstance(timestamp_micros, int):
+ raise TypeError("timestamp_micros must be int")
+ if abs(value) > _MAX_INCREMENT_VALUE:
+ raise ValueError(
+ "int values must be between -2**63 and 2**63 (64-bit signed int)"
+ )
+
+ if timestamp_micros < 0:
+ raise ValueError("timestamp must be non-negative")
+
+ self.family = family
+ self.qualifier = qualifier
+ self.value = value
+ self.timestamp = timestamp_micros
+
+ def _to_dict(self) -> dict[str, Any]:
+ return {
+ "add_to_cell": {
+ "family_name": self.family,
+ "column_qualifier": {"raw_value": self.qualifier},
+ "timestamp": {"raw_timestamp_micros": self.timestamp},
+ "input": {"int_value": self.value},
+ }
+ }
+
+ def is_idempotent(self) -> bool:
+ return False
+
+
+class RowMutationEntry:
+ """
+ A single entry in a `MutateRows` request.
+
+ This class represents a set of mutations to apply to a specific row in a
+ Bigtable table.
+
+ Args:
+ row_key: The key of the row to mutate.
+ mutations: The mutation or list of mutations to apply
+ to the row.
+
+ Raises:
+ ValueError: If `mutations` is empty or contains more than
+ `_MUTATE_ROWS_REQUEST_MUTATION_LIMIT` mutations.
+ """
+
+ def __init__(self, row_key: bytes | str, mutations: Mutation | list[Mutation]):
+ if isinstance(row_key, str):
+ row_key = row_key.encode("utf-8")
+ if isinstance(mutations, Mutation):
+ mutations = [mutations]
+ if len(mutations) == 0:
+ raise ValueError("mutations must not be empty")
+ elif len(mutations) > _MUTATE_ROWS_REQUEST_MUTATION_LIMIT:
+ raise ValueError(
+ f"entries must have <= {_MUTATE_ROWS_REQUEST_MUTATION_LIMIT} mutations"
+ )
+ self.row_key = row_key
+ self.mutations = tuple(mutations)
+
+ def _to_dict(self) -> dict[str, Any]:
+ """
+ Convert the mutation entry to a dictionary representation.
+
+ Returns:
+ dict[str, Any]: A dictionary representation of the mutation entry
+ """
+ return {
+ "row_key": self.row_key,
+ "mutations": [mutation._to_dict() for mutation in self.mutations],
+ }
+
+ def _to_pb(self) -> types_pb.MutateRowsRequest.Entry:
+ """
+ Convert the mutation entry to a protobuf representation.
+
+ Returns:
+ MutateRowsRequest.Entry: A protobuf representation of the mutation entry.
+ """
+ return types_pb.MutateRowsRequest.Entry(
+ row_key=self.row_key,
+ mutations=[mutation._to_pb() for mutation in self.mutations],
+ )
+
+ def is_idempotent(self) -> bool:
+ """
+ Check if all mutations in the entry are idempotent.
+
+ Returns:
+ bool: True if all mutations in the entry are idempotent, False otherwise.
+ """
+ return all(mutation.is_idempotent() for mutation in self.mutations)
+
+ def size(self) -> int:
+ """
+ Get the size of the mutation entry in bytes.
+
+ Returns:
+ int: The size of the mutation entry in bytes.
+ """
+ return getsizeof(self._to_dict())
+
+ @classmethod
+ def _from_dict(cls, input_dict: dict[str, Any]) -> RowMutationEntry:
+ """
+ Create a `RowMutationEntry` instance from a dictionary representation.
+
+ Args:
+ input_dict: A dictionary representation of the mutation entry.
+
+ Returns:
+ RowMutationEntry: A RowMutationEntry instance created from the dictionary.
+ """
+ return RowMutationEntry(
+ row_key=input_dict["row_key"],
+ mutations=[
+ Mutation._from_dict(mutation) for mutation in input_dict["mutations"]
+ ],
+ )
+
+
+@dataclass
+class _EntryWithProto:
+ """
+ A dataclass to hold a RowMutationEntry and its corresponding proto representation.
+
+ Used in _MutateRowsOperation to avoid repeated conversion of RowMutationEntry to proto.
+ """
+
+ entry: RowMutationEntry
+ proto: types_pb.MutateRowsRequest.Entry
diff --git a/google/cloud/bigtable/data/read_modify_write_rules.py b/google/cloud/bigtable/data/read_modify_write_rules.py
new file mode 100644
index 000000000..e4446f755
--- /dev/null
+++ b/google/cloud/bigtable/data/read_modify_write_rules.py
@@ -0,0 +1,112 @@
+# Copyright 2023 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.
+#
+from __future__ import annotations
+
+import abc
+
+import google.cloud.bigtable_v2.types.data as data_pb
+
+# value must fit in 64-bit signed integer
+_MAX_INCREMENT_VALUE = (1 << 63) - 1
+
+
+class ReadModifyWriteRule(abc.ABC):
+ """
+ Abstract base class for read-modify-write rules.
+ """
+
+ def __init__(self, family: str, qualifier: bytes | str):
+ qualifier = (
+ qualifier if isinstance(qualifier, bytes) else qualifier.encode("utf-8")
+ )
+ self.family = family
+ self.qualifier = qualifier
+
+ @abc.abstractmethod
+ def _to_dict(self) -> dict[str, str | bytes | int]:
+ raise NotImplementedError
+
+ def _to_pb(self) -> data_pb.ReadModifyWriteRule:
+ return data_pb.ReadModifyWriteRule(**self._to_dict())
+
+
+class IncrementRule(ReadModifyWriteRule):
+ """
+ Rule to increment a cell's value.
+
+ Args:
+ family:
+ The family name of the cell to increment.
+ qualifier:
+ The qualifier of the cell to increment.
+ increment_amount:
+ The amount to increment the cell's value. Must be between -2**63 and 2**63 (64-bit signed int).
+ Raises:
+ TypeError:
+ If increment_amount is not an integer.
+ ValueError:
+ If increment_amount is not between -2**63 and 2**63 (64-bit signed int).
+ """
+
+ def __init__(self, family: str, qualifier: bytes | str, increment_amount: int = 1):
+ if not isinstance(increment_amount, int):
+ raise TypeError("increment_amount must be an integer")
+ if abs(increment_amount) > _MAX_INCREMENT_VALUE:
+ raise ValueError(
+ "increment_amount must be between -2**63 and 2**63 (64-bit signed int)"
+ )
+ super().__init__(family, qualifier)
+ self.increment_amount = increment_amount
+
+ def _to_dict(self) -> dict[str, str | bytes | int]:
+ return {
+ "family_name": self.family,
+ "column_qualifier": self.qualifier,
+ "increment_amount": self.increment_amount,
+ }
+
+
+class AppendValueRule(ReadModifyWriteRule):
+ """
+ Rule to append a value to a cell's value.
+
+ Args:
+ family:
+ The family name of the cell to append to.
+ qualifier:
+ The qualifier of the cell to append to.
+ append_value:
+ The value to append to the cell's value.
+ Raises:
+ TypeError: If append_value is not bytes or str.
+ """
+
+ def __init__(self, family: str, qualifier: bytes | str, append_value: bytes | str):
+ append_value = (
+ append_value.encode("utf-8")
+ if isinstance(append_value, str)
+ else append_value
+ )
+ if not isinstance(append_value, bytes):
+ raise TypeError("append_value must be bytes or str")
+ super().__init__(family, qualifier)
+ self.append_value = append_value
+
+ def _to_dict(self) -> dict[str, str | bytes | int]:
+ return {
+ "family_name": self.family,
+ "column_qualifier": self.qualifier,
+ "append_value": self.append_value,
+ }
diff --git a/google/cloud/bigtable/data/read_rows_query.py b/google/cloud/bigtable/data/read_rows_query.py
new file mode 100644
index 000000000..7652bfbb9
--- /dev/null
+++ b/google/cloud/bigtable/data/read_rows_query.py
@@ -0,0 +1,536 @@
+# Copyright 2023 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.
+#
+from __future__ import annotations
+from typing import TYPE_CHECKING, Any
+from bisect import bisect_left
+from bisect import bisect_right
+from collections import defaultdict
+from google.cloud.bigtable.data.row_filters import RowFilter
+
+from google.cloud.bigtable_v2.types import RowRange as RowRangePB
+from google.cloud.bigtable_v2.types import RowSet as RowSetPB
+from google.cloud.bigtable_v2.types import ReadRowsRequest as ReadRowsRequestPB
+
+if TYPE_CHECKING:
+ from google.cloud.bigtable.data import RowKeySamples
+ from google.cloud.bigtable.data import ShardedQuery
+
+
+class RowRange:
+ """
+ Represents a range of keys in a ReadRowsQuery
+
+ Args:
+ start_key: The start key of the range. If empty, the range is unbounded on the left.
+ end_key: The end key of the range. If empty, the range is unbounded on the right.
+ start_is_inclusive: Whether the start key is inclusive. If None, the start key is
+ inclusive.
+ end_is_inclusive: Whether the end key is inclusive. If None, the end key is not inclusive.
+ Raises:
+ ValueError: if start_key is greater than end_key, or start_is_inclusive
+ ValueError: if end_is_inclusive is set when the corresponding key is None
+ ValueError: if start_key or end_key is not a string or bytes.
+ """
+
+ __slots__ = ("_pb",)
+
+ def __init__(
+ self,
+ start_key: str | bytes | None = None,
+ end_key: str | bytes | None = None,
+ start_is_inclusive: bool | None = None,
+ end_is_inclusive: bool | None = None,
+ ):
+ # convert empty key inputs to None for consistency
+ start_key = None if not start_key else start_key
+ end_key = None if not end_key else end_key
+ # check for invalid combinations of arguments
+ if start_is_inclusive is None:
+ start_is_inclusive = True
+
+ if end_is_inclusive is None:
+ end_is_inclusive = False
+ # ensure that start_key and end_key are bytes
+ if isinstance(start_key, str):
+ start_key = start_key.encode()
+ elif start_key is not None and not isinstance(start_key, bytes):
+ raise ValueError("start_key must be a string or bytes")
+ if isinstance(end_key, str):
+ end_key = end_key.encode()
+ elif end_key is not None and not isinstance(end_key, bytes):
+ raise ValueError("end_key must be a string or bytes")
+ # ensure that start_key is less than or equal to end_key
+ if start_key is not None and end_key is not None and start_key > end_key:
+ raise ValueError("start_key must be less than or equal to end_key")
+
+ init_dict = {}
+ if start_key is not None:
+ if start_is_inclusive:
+ init_dict["start_key_closed"] = start_key
+ else:
+ init_dict["start_key_open"] = start_key
+ if end_key is not None:
+ if end_is_inclusive:
+ init_dict["end_key_closed"] = end_key
+ else:
+ init_dict["end_key_open"] = end_key
+ self._pb = RowRangePB(**init_dict)
+
+ @property
+ def start_key(self) -> bytes | None:
+ """
+ Returns the start key of the range. If None, the range is unbounded on the left.
+ """
+ return self._pb.start_key_closed or self._pb.start_key_open or None
+
+ @property
+ def end_key(self) -> bytes | None:
+ """
+ Returns the end key of the range. If None, the range is unbounded on the right.
+
+ Returns:
+ bytes | None: The end key of the range, or None if the range is unbounded on the right.
+ """
+ return self._pb.end_key_closed or self._pb.end_key_open or None
+
+ @property
+ def start_is_inclusive(self) -> bool:
+ """
+ Indicates if the range is inclusive of the start key.
+
+ If the range is unbounded on the left, this will return True.
+
+ Returns:
+ bool: Whether the range is inclusive of the start key.
+ """
+ return not bool(self._pb.start_key_open)
+
+ @property
+ def end_is_inclusive(self) -> bool:
+ """
+ Indicates if the range is inclusive of the end key.
+
+ If the range is unbounded on the right, this will return True.
+
+ Returns:
+ bool: Whether the range is inclusive of the end key.
+ """
+ return not bool(self._pb.end_key_open)
+
+ def _to_pb(self) -> RowRangePB:
+ """
+ Converts this object to a protobuf
+
+ Returns:
+ RowRangePB: The protobuf representation of this object
+ """
+ return self._pb
+
+ @classmethod
+ def _from_pb(cls, data: RowRangePB) -> RowRange:
+ """
+ Creates a RowRange from a protobuf
+
+ Args:
+ data (RowRangePB): The protobuf to convert
+ Returns:
+ RowRange: The converted RowRange
+ """
+ instance = cls()
+ instance._pb = data
+ return instance
+
+ @classmethod
+ def _from_dict(cls, data: dict[str, bytes | str]) -> RowRange:
+ """
+ Creates a RowRange from a protobuf
+
+ Args:
+ data (dict[str, bytes | str]): The dictionary to convert
+ Returns:
+ RowRange: The converted RowRange
+ """
+ formatted_data = {
+ k: v.encode() if isinstance(v, str) else v for k, v in data.items()
+ }
+ instance = cls()
+ instance._pb = RowRangePB(**formatted_data)
+ return instance
+
+ def __bool__(self) -> bool:
+ """
+ Empty RowRanges (representing a full table scan) are falsy, because
+ they can be substituted with None. Non-empty RowRanges are truthy.
+
+ Returns:
+ bool: True if the RowRange is not empty, False otherwise
+ """
+ return bool(
+ self._pb.start_key_closed
+ or self._pb.start_key_open
+ or self._pb.end_key_closed
+ or self._pb.end_key_open
+ )
+
+ def __eq__(self, other: Any) -> bool:
+ if not isinstance(other, RowRange):
+ return NotImplemented
+ return self._pb == other._pb
+
+ def __str__(self) -> str:
+ """
+ Represent range as a string, e.g. "[b'a', b'z)"
+
+ Unbounded start or end keys are represented as "-inf" or "+inf"
+
+ Returns:
+ str: The string representation of the range
+ """
+ left = "[" if self.start_is_inclusive else "("
+ right = "]" if self.end_is_inclusive else ")"
+ start = repr(self.start_key) if self.start_key is not None else "-inf"
+ end = repr(self.end_key) if self.end_key is not None else "+inf"
+ return f"{left}{start}, {end}{right}"
+
+ def __repr__(self) -> str:
+ args_list = []
+ args_list.append(f"start_key={self.start_key!r}")
+ args_list.append(f"end_key={self.end_key!r}")
+ if self.start_is_inclusive is False:
+ # only show start_is_inclusive if it is different from the default
+ args_list.append(f"start_is_inclusive={self.start_is_inclusive}")
+ if self.end_is_inclusive is True and self.end_key is not None:
+ # only show end_is_inclusive if it is different from the default
+ args_list.append(f"end_is_inclusive={self.end_is_inclusive}")
+ return f"RowRange({', '.join(args_list)})"
+
+
+class ReadRowsQuery:
+ """
+ Class to encapsulate details of a read row request
+
+ Args:
+ row_keys: row keys to include in the query
+ a query can contain multiple keys, but ranges should be preferred
+ row_ranges: ranges of rows to include in the query
+ limit: the maximum number of rows to return. None or 0 means no limit
+ default: None (no limit)
+ row_filter: a RowFilter to apply to the query
+ """
+
+ slots = ("_limit", "_filter", "_row_set")
+
+ def __init__(
+ self,
+ row_keys: list[str | bytes] | str | bytes | None = None,
+ row_ranges: list[RowRange] | RowRange | None = None,
+ limit: int | None = None,
+ row_filter: RowFilter | None = None,
+ ):
+ if row_keys is None:
+ row_keys = []
+ if row_ranges is None:
+ row_ranges = []
+ if not isinstance(row_ranges, list):
+ row_ranges = [row_ranges]
+ if not isinstance(row_keys, list):
+ row_keys = [row_keys]
+ row_keys = [key.encode() if isinstance(key, str) else key for key in row_keys]
+ self._row_set = RowSetPB(
+ row_keys=row_keys, row_ranges=[r._pb for r in row_ranges]
+ )
+ self.limit = limit or None
+ self.filter = row_filter
+
+ @property
+ def row_keys(self) -> list[bytes]:
+ """
+ Return the row keys in this query
+
+ Returns:
+ list[bytes]: the row keys in this query
+ """
+ return list(self._row_set.row_keys)
+
+ @property
+ def row_ranges(self) -> list[RowRange]:
+ """
+ Return the row ranges in this query
+
+ Returns:
+ list[RowRange]: the row ranges in this query
+ """
+ return [RowRange._from_pb(r) for r in self._row_set.row_ranges]
+
+ @property
+ def limit(self) -> int | None:
+ """
+ Return the maximum number of rows to return by this query
+
+ None or 0 means no limit
+
+ Returns:
+ int | None: the maximum number of rows to return by this query
+ """
+ return self._limit or None
+
+ @limit.setter
+ def limit(self, new_limit: int | None):
+ """
+ Set the maximum number of rows to return by this query.
+
+ None or 0 means no limit
+
+ Args:
+ new_limit: the new limit to apply to this query
+ Raises:
+ ValueError: if new_limit is < 0
+ """
+ if new_limit is not None and new_limit < 0:
+ raise ValueError("limit must be >= 0")
+ self._limit = new_limit
+
+ @property
+ def filter(self) -> RowFilter | None:
+ """
+ Return the RowFilter applied to this query
+
+ Returns:
+ RowFilter | None: the RowFilter applied to this query
+ """
+ return self._filter
+
+ @filter.setter
+ def filter(self, row_filter: RowFilter | None):
+ """
+ Set a RowFilter to apply to this query
+
+ Args:
+ row_filter: a RowFilter to apply to this query
+ """
+ self._filter = row_filter
+
+ def add_key(self, row_key: str | bytes):
+ """
+ Add a row key to this query
+
+ A query can contain multiple keys, but ranges should be preferred
+
+ Args:
+ row_key: a key to add to this query
+ Raises:
+ ValueError: if an input is not a string or bytes
+ """
+ if isinstance(row_key, str):
+ row_key = row_key.encode()
+ elif not isinstance(row_key, bytes):
+ raise ValueError("row_key must be string or bytes")
+ if row_key not in self._row_set.row_keys:
+ self._row_set.row_keys.append(row_key)
+
+ def add_range(
+ self,
+ row_range: RowRange,
+ ):
+ """
+ Add a range of row keys to this query.
+
+ Args:
+ row_range: a range of row keys to add to this query
+ """
+ if row_range not in self.row_ranges:
+ self._row_set.row_ranges.append(row_range._pb)
+
+ def shard(self, shard_keys: RowKeySamples) -> ShardedQuery:
+ """
+ Split this query into multiple queries that can be evenly distributed
+ across nodes and run in parallel
+
+ Args:
+ shard_keys: a list of row keys that define the boundaries of segments.
+ Returns:
+ ShardedQuery: a ShardedQuery that can be used in sharded_read_rows calls
+ Raises:
+ AttributeError: if the query contains a limit
+ """
+ if self.limit is not None:
+ raise AttributeError("Cannot shard query with a limit")
+ if len(self.row_keys) == 0 and len(self.row_ranges) == 0:
+ # empty query represents full scan
+ # ensure that we have at least one key or range
+ full_scan_query = ReadRowsQuery(
+ row_ranges=RowRange(), row_filter=self.filter
+ )
+ return full_scan_query.shard(shard_keys)
+
+ sharded_queries: dict[int, ReadRowsQuery] = defaultdict(
+ lambda: ReadRowsQuery(row_filter=self.filter)
+ )
+ # the split_points divde our key space into segments
+ # each split_point defines last key that belongs to a segment
+ # our goal is to break up the query into subqueries that each operate in a single segment
+ split_points = [sample[0] for sample in shard_keys if sample[0]]
+
+ # handle row_keys
+ # use binary search to find the segment that each key belongs to
+ for this_key in list(self.row_keys):
+ # bisect_left: in case of exact match, pick left side (keys are inclusive ends)
+ segment_index = bisect_left(split_points, this_key)
+ sharded_queries[segment_index].add_key(this_key)
+
+ # handle row_ranges
+ for this_range in self.row_ranges:
+ # defer to _shard_range helper
+ for segment_index, added_range in self._shard_range(
+ this_range, split_points
+ ):
+ sharded_queries[segment_index].add_range(added_range)
+ # return list of queries ordered by segment index
+ # pull populated segments out of sharded_queries dict
+ keys = sorted(list(sharded_queries.keys()))
+ # return list of queries
+ return [sharded_queries[k] for k in keys]
+
+ @staticmethod
+ def _shard_range(
+ orig_range: RowRange, split_points: list[bytes]
+ ) -> list[tuple[int, RowRange]]:
+ """
+ Helper function for sharding row_range into subranges that fit into
+ segments of the key-space, determined by split_points
+
+ Args:
+ orig_range: a row range to split
+ split_points: a list of row keys that define the boundaries of segments.
+ each point represents the inclusive end of a segment
+ Returns:
+ list[tuple[int, RowRange]]: a list of tuples, containing a segment index and a new sub-range.
+ """
+ # 1. find the index of the segment the start key belongs to
+ if orig_range.start_key is None:
+ # if range is open on the left, include first segment
+ start_segment = 0
+ else:
+ # use binary search to find the segment the start key belongs to
+ # bisect method determines how we break ties when the start key matches a split point
+ # if inclusive, bisect_left to the left segment, otherwise bisect_right
+ bisect = bisect_left if orig_range.start_is_inclusive else bisect_right
+ start_segment = bisect(split_points, orig_range.start_key)
+
+ # 2. find the index of the segment the end key belongs to
+ if orig_range.end_key is None:
+ # if range is open on the right, include final segment
+ end_segment = len(split_points)
+ else:
+ # use binary search to find the segment the end key belongs to.
+ end_segment = bisect_left(
+ split_points, orig_range.end_key, lo=start_segment
+ )
+ # note: end_segment will always bisect_left, because split points represent inclusive ends
+ # whether the end_key is includes the split point or not, the result is the same segment
+ # 3. create new range definitions for each segment this_range spans
+ if start_segment == end_segment:
+ # this_range is contained in a single segment.
+ # Add this_range to that segment's query only
+ return [(start_segment, orig_range)]
+ else:
+ results: list[tuple[int, RowRange]] = []
+ # this_range spans multiple segments. Create a new range for each segment's query
+ # 3a. add new range for first segment this_range spans
+ # first range spans from start_key to the split_point representing the last key in the segment
+ last_key_in_first_segment = split_points[start_segment]
+ start_range = RowRange(
+ start_key=orig_range.start_key,
+ start_is_inclusive=orig_range.start_is_inclusive,
+ end_key=last_key_in_first_segment,
+ end_is_inclusive=True,
+ )
+ results.append((start_segment, start_range))
+ # 3b. add new range for last segment this_range spans
+ # we start the final range using the end key from of the previous segment, with is_inclusive=False
+ previous_segment = end_segment - 1
+ last_key_before_segment = split_points[previous_segment]
+ end_range = RowRange(
+ start_key=last_key_before_segment,
+ start_is_inclusive=False,
+ end_key=orig_range.end_key,
+ end_is_inclusive=orig_range.end_is_inclusive,
+ )
+ results.append((end_segment, end_range))
+ # 3c. add new spanning range to all segments other than the first and last
+ for this_segment in range(start_segment + 1, end_segment):
+ prev_segment = this_segment - 1
+ prev_end_key = split_points[prev_segment]
+ this_end_key = split_points[prev_segment + 1]
+ new_range = RowRange(
+ start_key=prev_end_key,
+ start_is_inclusive=False,
+ end_key=this_end_key,
+ end_is_inclusive=True,
+ )
+ results.append((this_segment, new_range))
+ return results
+
+ def _to_pb(self, table) -> ReadRowsRequestPB:
+ """
+ Convert this query into a dictionary that can be used to construct a
+ ReadRowsRequest protobuf
+ """
+ return ReadRowsRequestPB(
+ app_profile_id=table.app_profile_id,
+ filter=self.filter._to_pb() if self.filter else None,
+ rows_limit=self.limit or 0,
+ rows=self._row_set,
+ **table._request_path,
+ )
+
+ def __eq__(self, other):
+ """
+ RowRanges are equal if they have the same row keys, row ranges,
+ filter and limit, or if they both represent a full scan with the
+ same filter and limit
+
+ Args:
+ other: the object to compare to
+ Returns:
+ bool: True if the objects are equal, False otherwise
+ """
+ if not isinstance(other, ReadRowsQuery):
+ return False
+ # empty queries are equal
+ if len(self.row_keys) == 0 and len(other.row_keys) == 0:
+ this_range_empty = len(self.row_ranges) == 0 or all(
+ [bool(r) is False for r in self.row_ranges]
+ )
+ other_range_empty = len(other.row_ranges) == 0 or all(
+ [bool(r) is False for r in other.row_ranges]
+ )
+ if this_range_empty and other_range_empty:
+ return self.filter == other.filter and self.limit == other.limit
+ # otherwise, sets should have same sizes
+ if len(self.row_keys) != len(other.row_keys):
+ return False
+ if len(self.row_ranges) != len(other.row_ranges):
+ return False
+ ranges_match = all([row in other.row_ranges for row in self.row_ranges])
+ return (
+ self.row_keys == other.row_keys
+ and ranges_match
+ and self.filter == other.filter
+ and self.limit == other.limit
+ )
+
+ def __repr__(self):
+ return f"ReadRowsQuery(row_keys={list(self.row_keys)}, row_ranges={list(self.row_ranges)}, row_filter={self.filter}, limit={self.limit})"
diff --git a/google/cloud/bigtable/data/row.py b/google/cloud/bigtable/data/row.py
new file mode 100644
index 000000000..50e65a958
--- /dev/null
+++ b/google/cloud/bigtable/data/row.py
@@ -0,0 +1,535 @@
+# Copyright 2023 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.
+#
+from __future__ import annotations
+
+from collections import OrderedDict
+from typing import Generator, overload, Any
+from functools import total_ordering
+
+from google.cloud.bigtable_v2.types import Row as RowPB
+
+# Type aliases used internally for readability.
+_family_type = str
+_qualifier_type = bytes
+
+
+class Row:
+ """
+ Model class for row data returned from server
+
+ Does not represent all data contained in the row, only data returned by a
+ query.
+ Expected to be read-only to users, and written by backend
+
+ Can be indexed by family and qualifier to get cells in the row::
+
+ cells = row["family", "qualifier"]
+
+ Args:
+ key: Row key
+ cells: List of cells in the row
+ """
+
+ __slots__ = ("row_key", "cells", "_index_data")
+
+ def __init__(
+ self,
+ key: bytes,
+ cells: list[Cell],
+ ):
+ """
+ Row objects are not intended to be created by users.
+ They are returned by the Bigtable backend.
+ """
+ self.row_key = key
+ self.cells: list[Cell] = cells
+ # index is lazily created when needed
+ self._index_data: OrderedDict[
+ _family_type, OrderedDict[_qualifier_type, list[Cell]]
+ ] | None = None
+
+ @property
+ def _index(
+ self,
+ ) -> OrderedDict[_family_type, OrderedDict[_qualifier_type, list[Cell]]]:
+ """
+ Returns an index of cells associated with each family and qualifier.
+
+ The index is lazily created when needed
+
+ Returns:
+ OrderedDict: Index of cells
+ """
+ if self._index_data is None:
+ self._index_data = OrderedDict()
+ for cell in self.cells:
+ self._index_data.setdefault(cell.family, OrderedDict()).setdefault(
+ cell.qualifier, []
+ ).append(cell)
+ return self._index_data
+
+ @classmethod
+ def _from_pb(cls, row_pb: RowPB) -> Row:
+ """
+ Creates a row from a protobuf representation
+
+ Row objects are not intended to be created by users.
+ They are returned by the Bigtable backend.
+
+ Args:
+ row_pb (RowPB): Protobuf representation of the row
+ Returns:
+ Row: Row object created from the protobuf representation
+ """
+ row_key: bytes = row_pb.key
+ cell_list: list[Cell] = []
+ for family in row_pb.families:
+ for column in family.columns:
+ for cell in column.cells:
+ new_cell = Cell(
+ value=cell.value,
+ row_key=row_key,
+ family=family.name,
+ qualifier=column.qualifier,
+ timestamp_micros=cell.timestamp_micros,
+ labels=list(cell.labels) if cell.labels else None,
+ )
+ cell_list.append(new_cell)
+ return cls(row_key, cells=cell_list)
+
+ def get_cells(
+ self, family: str | None = None, qualifier: str | bytes | None = None
+ ) -> list[Cell]:
+ """
+ Returns cells sorted in Bigtable native order:
+ - Family lexicographically ascending
+ - Qualifier ascending
+ - Timestamp in reverse chronological order
+
+ If family or qualifier not passed, will include all
+
+ Can also be accessed through indexing::
+ cells = row["family", "qualifier"]
+ cells = row["family"]
+
+ Args:
+ family: family to filter cells by
+ qualifier: qualifier to filter cells by
+ Returns:
+ list[Cell]: List of cells in the row matching the filter
+ Raises:
+ ValueError: If family or qualifier is not found in the row
+ """
+ if family is None:
+ if qualifier is not None:
+ # get_cells(None, "qualifier") is not allowed
+ raise ValueError("Qualifier passed without family")
+ else:
+ # return all cells on get_cells()
+ return self.cells
+ if qualifier is None:
+ # return all cells in family on get_cells(family)
+ return list(self._get_all_from_family(family))
+ if isinstance(qualifier, str):
+ qualifier = qualifier.encode("utf-8")
+ # return cells in family and qualifier on get_cells(family, qualifier)
+ if family not in self._index:
+ raise ValueError(f"Family '{family}' not found in row '{self.row_key!r}'")
+ if qualifier not in self._index[family]:
+ raise ValueError(
+ f"Qualifier '{qualifier!r}' not found in family '{family}' in row '{self.row_key!r}'"
+ )
+ return self._index[family][qualifier]
+
+ def _get_all_from_family(self, family: str) -> Generator[Cell, None, None]:
+ """
+ Returns all cells in the row for the family_id
+
+ Args:
+ family: family to filter cells by
+ Yields:
+ Cell: cells in the row for the family_id
+ Raises:
+ ValueError: If family is not found in the row
+ """
+ if family not in self._index:
+ raise ValueError(f"Family '{family}' not found in row '{self.row_key!r}'")
+ for qualifier in self._index[family]:
+ yield from self._index[family][qualifier]
+
+ def __str__(self) -> str:
+ """
+ Human-readable string representation::
+
+ {
+ (family='fam', qualifier=b'col'): [b'value', (+1 more),],
+ (family='fam', qualifier=b'col2'): [b'other'],
+ }
+
+ Returns:
+ str: Human-readable string representation of the row
+ """
+ output = ["{"]
+ for family, qualifier in self._get_column_components():
+ cell_list = self[family, qualifier]
+ line = [f" (family={family!r}, qualifier={qualifier!r}): "]
+ if len(cell_list) == 0:
+ line.append("[],")
+ elif len(cell_list) == 1:
+ line.append(f"[{cell_list[0]}],")
+ else:
+ line.append(f"[{cell_list[0]}, (+{len(cell_list) - 1} more)],")
+ output.append("".join(line))
+ output.append("}")
+ return "\n".join(output)
+
+ def __repr__(self):
+ cell_str_buffer = ["{"]
+ for family, qualifier in self._get_column_components():
+ cell_list = self[family, qualifier]
+ repr_list = [cell._to_dict() for cell in cell_list]
+ cell_str_buffer.append(f" ('{family}', {qualifier!r}): {repr_list},")
+ cell_str_buffer.append("}")
+ cell_str = "\n".join(cell_str_buffer)
+ output = f"Row(key={self.row_key!r}, cells={cell_str})"
+ return output
+
+ def _to_dict(self) -> dict[str, Any]:
+ """
+ Returns a dictionary representation of the cell in the Bigtable Row
+ proto format
+
+ https://cloud.google.com/bigtable/docs/reference/data/rpc/google.bigtable.v2#row
+ """
+ family_list = []
+ for family_name, qualifier_dict in self._index.items():
+ qualifier_list = []
+ for qualifier_name, cell_list in qualifier_dict.items():
+ cell_dicts = [cell._to_dict() for cell in cell_list]
+ qualifier_list.append(
+ {"qualifier": qualifier_name, "cells": cell_dicts}
+ )
+ family_list.append({"name": family_name, "columns": qualifier_list})
+ return {"key": self.row_key, "families": family_list}
+
+ # Sequence and Mapping methods
+ def __iter__(self):
+ """
+ Allow iterating over all cells in the row
+
+ Returns:
+ Iterator: Iterator over the cells in the row
+ """
+ return iter(self.cells)
+
+ def __contains__(self, item):
+ """
+ Implements `in` operator
+
+ Works for both cells in the internal list, and `family` or
+ `(family, qualifier)` pairs associated with the cells
+
+ Args:
+ item: item to check for in the row
+ Returns:
+ bool: True if item is in the row, False otherwise
+ """
+ if isinstance(item, _family_type):
+ return item in self._index
+ elif (
+ isinstance(item, tuple)
+ and isinstance(item[0], _family_type)
+ and isinstance(item[1], (bytes, str))
+ ):
+ q = item[1] if isinstance(item[1], bytes) else item[1].encode("utf-8")
+ return item[0] in self._index and q in self._index[item[0]]
+ # check if Cell is in Row
+ return item in self.cells
+
+ @overload
+ def __getitem__(
+ self,
+ index: str | tuple[str, bytes | str],
+ ) -> list[Cell]:
+ # overload signature for type checking
+ pass
+
+ @overload
+ def __getitem__(self, index: int) -> Cell:
+ # overload signature for type checking
+ pass
+
+ @overload
+ def __getitem__(self, index: slice) -> list[Cell]:
+ # overload signature for type checking
+ pass
+
+ def __getitem__(self, index):
+ """
+ Implements [] indexing
+
+ Supports indexing by family, (family, qualifier) pair,
+ numerical index, and index slicing
+ """
+ if isinstance(index, _family_type):
+ return self.get_cells(family=index)
+ elif (
+ isinstance(index, tuple)
+ and isinstance(index[0], _family_type)
+ and isinstance(index[1], (bytes, str))
+ ):
+ return self.get_cells(family=index[0], qualifier=index[1])
+ elif isinstance(index, int) or isinstance(index, slice):
+ # index is int or slice
+ return self.cells[index]
+ else:
+ raise TypeError(
+ "Index must be family_id, (family_id, qualifier), int, or slice"
+ )
+
+ def __len__(self):
+ """
+ Returns the number of cells in the row
+
+ Returns:
+ int: Number of cells in the row
+ """
+ return len(self.cells)
+
+ def _get_column_components(self) -> list[tuple[str, bytes]]:
+ """
+ Returns a list of (family, qualifier) pairs associated with the cells
+
+ Pairs can be used for indexing
+
+ Returns:
+ list[tuple[str, bytes]]: List of (family, qualifier) pairs
+ """
+ return [(f, q) for f in self._index for q in self._index[f]]
+
+ def __eq__(self, other):
+ """
+ Implements `==` operator
+
+ Returns:
+ bool: True if rows are equal, False otherwise
+ """
+ # for performance reasons, check row metadata
+ # before checking individual cells
+ if not isinstance(other, Row):
+ return False
+ if self.row_key != other.row_key:
+ return False
+ if len(self.cells) != len(other.cells):
+ return False
+ components = self._get_column_components()
+ other_components = other._get_column_components()
+ if len(components) != len(other_components):
+ return False
+ if components != other_components:
+ return False
+ for family, qualifier in components:
+ if len(self[family, qualifier]) != len(other[family, qualifier]):
+ return False
+ # compare individual cell lists
+ if self.cells != other.cells:
+ return False
+ return True
+
+ def __ne__(self, other) -> bool:
+ """
+ Implements `!=` operator
+
+ Returns:
+ bool: True if rows are not equal, False otherwise
+ """
+ return not self == other
+
+
+@total_ordering
+class Cell:
+ """
+ Model class for cell data
+
+ Does not represent all data contained in the cell, only data returned by a
+ query.
+ Expected to be read-only to users, and written by backend
+
+ Args:
+ value: the byte string value of the cell
+ row_key: the row key of the cell
+ family: the family associated with the cell
+ qualifier: the column qualifier associated with the cell
+ timestamp_micros: the timestamp of the cell in microseconds
+ labels: the list of labels associated with the cell
+ """
+
+ __slots__ = (
+ "value",
+ "row_key",
+ "family",
+ "qualifier",
+ "timestamp_micros",
+ "labels",
+ )
+
+ def __init__(
+ self,
+ value: bytes,
+ row_key: bytes,
+ family: str,
+ qualifier: bytes | str,
+ timestamp_micros: int,
+ labels: list[str] | None = None,
+ ):
+ # Cell objects are not intended to be constructed by users.
+ # They are returned by the Bigtable backend.
+ self.value = value
+ self.row_key = row_key
+ self.family = family
+ if isinstance(qualifier, str):
+ qualifier = qualifier.encode()
+ self.qualifier = qualifier
+ self.timestamp_micros = timestamp_micros
+ self.labels = labels if labels is not None else []
+
+ def __int__(self) -> int:
+ """
+ Allows casting cell to int
+ Interprets value as a 64-bit big-endian signed integer, as expected by
+ ReadModifyWrite increment rule
+
+ Returns:
+ int: Value of the cell as a 64-bit big-endian signed integer
+ """
+ return int.from_bytes(self.value, byteorder="big", signed=True)
+
+ def _to_dict(self) -> dict[str, Any]:
+ """
+ Returns a dictionary representation of the cell in the Bigtable Cell
+ proto format
+
+ https://cloud.google.com/bigtable/docs/reference/data/rpc/google.bigtable.v2#cell
+
+ Returns:
+ dict: Dictionary representation of the cell
+ """
+ cell_dict: dict[str, Any] = {
+ "value": self.value,
+ }
+ cell_dict["timestamp_micros"] = self.timestamp_micros
+ if self.labels:
+ cell_dict["labels"] = self.labels
+ return cell_dict
+
+ def __str__(self) -> str:
+ """
+ Allows casting cell to str
+ Prints encoded byte string, same as printing value directly.
+
+ Returns:
+ str: Encoded byte string of the value
+ """
+ return str(self.value)
+
+ def __repr__(self):
+ """
+ Returns a string representation of the cell
+
+ Returns:
+ str: String representation of the cell
+ """
+ return f"Cell(value={self.value!r}, row_key={self.row_key!r}, family='{self.family}', qualifier={self.qualifier!r}, timestamp_micros={self.timestamp_micros}, labels={self.labels})"
+
+ """For Bigtable native ordering"""
+
+ def __lt__(self, other) -> bool:
+ """
+ Implements `<` operator
+
+ Args:
+ other: Cell to compare with
+ Returns:
+ bool: True if this cell is less than the other cell, False otherwise
+ Raises:
+ NotImplementedError: If other is not a Cell
+ """
+ if not isinstance(other, Cell):
+ raise NotImplementedError
+ this_ordering = (
+ self.family,
+ self.qualifier,
+ -self.timestamp_micros,
+ self.value,
+ self.labels,
+ )
+ other_ordering = (
+ other.family,
+ other.qualifier,
+ -other.timestamp_micros,
+ other.value,
+ other.labels,
+ )
+ return this_ordering < other_ordering
+
+ def __eq__(self, other) -> bool:
+ """
+ Implements `==` operator
+
+ Args:
+ other: Cell to compare with
+ Returns:
+ bool: True if cells are equal, False otherwise
+ """
+ if not isinstance(other, Cell):
+ return False
+ return (
+ self.row_key == other.row_key
+ and self.family == other.family
+ and self.qualifier == other.qualifier
+ and self.value == other.value
+ and self.timestamp_micros == other.timestamp_micros
+ and len(self.labels) == len(other.labels)
+ and all([label in other.labels for label in self.labels])
+ )
+
+ def __ne__(self, other) -> bool:
+ """
+ Implements `!=` operator
+
+ Args:
+ other: Cell to compare with
+ Returns:
+ bool: True if cells are not equal, False otherwise
+ """
+ return not self == other
+
+ def __hash__(self):
+ """
+ Implements `hash()` function to fingerprint cell
+
+ Returns:
+ int: hash value of the cell
+ """
+ return hash(
+ (
+ self.row_key,
+ self.family,
+ self.qualifier,
+ self.value,
+ self.timestamp_micros,
+ tuple(self.labels),
+ )
+ )
diff --git a/google/cloud/bigtable/data/row_filters.py b/google/cloud/bigtable/data/row_filters.py
new file mode 100644
index 000000000..9f09133d5
--- /dev/null
+++ b/google/cloud/bigtable/data/row_filters.py
@@ -0,0 +1,968 @@
+# Copyright 2016 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.
+
+"""Filters for Google Cloud Bigtable Row classes."""
+from __future__ import annotations
+
+import struct
+
+from typing import Any, Sequence, TYPE_CHECKING, overload
+from abc import ABC, abstractmethod
+
+from google.cloud._helpers import _microseconds_from_datetime # type: ignore
+from google.cloud._helpers import _to_bytes # type: ignore
+from google.cloud.bigtable_v2.types import data as data_v2_pb2
+
+if TYPE_CHECKING:
+ # import dependencies when type checking
+ from datetime import datetime
+
+_PACK_I64 = struct.Struct(">q").pack
+
+
+class RowFilter(ABC):
+ """Basic filter to apply to cells in a row.
+
+ These values can be combined via :class:`RowFilterChain`,
+ :class:`RowFilterUnion` and :class:`ConditionalRowFilter`.
+
+ .. note::
+
+ This class is a do-nothing base class for all row filters.
+ """
+
+ def _to_pb(self) -> data_v2_pb2.RowFilter:
+ """Converts the row filter to a protobuf.
+
+ Returns: The converted current object.
+ """
+ return data_v2_pb2.RowFilter(**self._to_dict())
+
+ @abstractmethod
+ def _to_dict(self) -> dict[str, Any]:
+ """Converts the row filter to a dict representation."""
+ pass
+
+ def __repr__(self) -> str:
+ return f"{self.__class__.__name__}()"
+
+
+class _BoolFilter(RowFilter, ABC):
+ """Row filter that uses a boolean flag.
+
+ :type flag: bool
+ :param flag: An indicator if a setting is turned on or off.
+ """
+
+ def __init__(self, flag: bool):
+ self.flag = flag
+
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return other.flag == self.flag
+
+ def __ne__(self, other):
+ return not self == other
+
+ def __repr__(self) -> str:
+ return f"{self.__class__.__name__}(flag={self.flag})"
+
+
+class SinkFilter(_BoolFilter):
+ """Advanced row filter to skip parent filters.
+
+ :type flag: bool
+ :param flag: ADVANCED USE ONLY. Hook for introspection into the row filter.
+ Outputs all cells directly to the output of the read rather
+ than to any parent filter. Cannot be used within the
+ ``predicate_filter``, ``true_filter``, or ``false_filter``
+ of a :class:`ConditionalRowFilter`.
+ """
+
+ def _to_dict(self) -> dict[str, Any]:
+ """Converts the row filter to a dict representation."""
+ return {"sink": self.flag}
+
+
+class PassAllFilter(_BoolFilter):
+ """Row filter equivalent to not filtering at all.
+
+ :type flag: bool
+ :param flag: Matches all cells, regardless of input. Functionally
+ equivalent to leaving ``filter`` unset, but included for
+ completeness.
+ """
+
+ def _to_dict(self) -> dict[str, Any]:
+ """Converts the row filter to a dict representation."""
+ return {"pass_all_filter": self.flag}
+
+
+class BlockAllFilter(_BoolFilter):
+ """Row filter that doesn't match any cells.
+
+ :type flag: bool
+ :param flag: Does not match any cells, regardless of input. Useful for
+ temporarily disabling just part of a filter.
+ """
+
+ def _to_dict(self) -> dict[str, Any]:
+ """Converts the row filter to a dict representation."""
+ return {"block_all_filter": self.flag}
+
+
+class _RegexFilter(RowFilter, ABC):
+ """Row filter that uses a regular expression.
+
+ The ``regex`` must be valid RE2 patterns. See Google's
+ `RE2 reference`_ for the accepted syntax.
+
+ .. _RE2 reference: https://github.com/google/re2/wiki/Syntax
+
+ :type regex: bytes or str
+ :param regex:
+ A regular expression (RE2) for some row filter. String values
+ will be encoded as ASCII.
+ """
+
+ def __init__(self, regex: str | bytes):
+ self.regex: bytes = _to_bytes(regex)
+
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return other.regex == self.regex
+
+ def __ne__(self, other):
+ return not self == other
+
+ def __repr__(self) -> str:
+ return f"{self.__class__.__name__}(regex={self.regex!r})"
+
+
+class RowKeyRegexFilter(_RegexFilter):
+ """Row filter for a row key regular expression.
+
+ The ``regex`` must be valid RE2 patterns. See Google's
+ `RE2 reference`_ for the accepted syntax.
+
+ .. _RE2 reference: https://github.com/google/re2/wiki/Syntax
+
+ .. note::
+
+ Special care need be used with the expression used. Since
+ each of these properties can contain arbitrary bytes, the ``\\C``
+ escape sequence must be used if a true wildcard is desired. The ``.``
+ character will not match the new line character ``\\n``, which may be
+ present in a binary value.
+
+ :type regex: bytes
+ :param regex: A regular expression (RE2) to match cells from rows with row
+ keys that satisfy this regex. For a
+ ``CheckAndMutateRowRequest``, this filter is unnecessary
+ since the row key is already specified.
+ """
+
+ def _to_dict(self) -> dict[str, Any]:
+ """Converts the row filter to a dict representation."""
+ return {"row_key_regex_filter": self.regex}
+
+
+class RowSampleFilter(RowFilter):
+ """Matches all cells from a row with probability p.
+
+ :type sample: float
+ :param sample: The probability of matching a cell (must be in the
+ interval ``(0, 1)`` The end points are excluded).
+ """
+
+ def __init__(self, sample: float):
+ self.sample: float = sample
+
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return other.sample == self.sample
+
+ def __ne__(self, other):
+ return not self == other
+
+ def _to_dict(self) -> dict[str, Any]:
+ """Converts the row filter to a dict representation."""
+ return {"row_sample_filter": self.sample}
+
+ def __repr__(self) -> str:
+ return f"{self.__class__.__name__}(sample={self.sample})"
+
+
+class FamilyNameRegexFilter(_RegexFilter):
+ """Row filter for a family name regular expression.
+
+ The ``regex`` must be valid RE2 patterns. See Google's
+ `RE2 reference`_ for the accepted syntax.
+
+ .. _RE2 reference: https://github.com/google/re2/wiki/Syntax
+
+ :type regex: str
+ :param regex: A regular expression (RE2) to match cells from columns in a
+ given column family. For technical reasons, the regex must
+ not contain the ``':'`` character, even if it is not being
+ used as a literal.
+ """
+
+ def _to_dict(self) -> dict[str, Any]:
+ """Converts the row filter to a dict representation."""
+ return {"family_name_regex_filter": self.regex}
+
+
+class ColumnQualifierRegexFilter(_RegexFilter):
+ """Row filter for a column qualifier regular expression.
+
+ The ``regex`` must be valid RE2 patterns. See Google's
+ `RE2 reference`_ for the accepted syntax.
+
+ .. _RE2 reference: https://github.com/google/re2/wiki/Syntax
+
+ .. note::
+
+ Special care need be used with the expression used. Since
+ each of these properties can contain arbitrary bytes, the ``\\C``
+ escape sequence must be used if a true wildcard is desired. The ``.``
+ character will not match the new line character ``\\n``, which may be
+ present in a binary value.
+
+ :type regex: bytes
+ :param regex: A regular expression (RE2) to match cells from column that
+ match this regex (irrespective of column family).
+ """
+
+ def _to_dict(self) -> dict[str, Any]:
+ """Converts the row filter to a dict representation."""
+ return {"column_qualifier_regex_filter": self.regex}
+
+
+class TimestampRange(object):
+ """Range of time with inclusive lower and exclusive upper bounds.
+
+ :type start: :class:`datetime.datetime`
+ :param start: (Optional) The (inclusive) lower bound of the timestamp
+ range. If omitted, defaults to Unix epoch.
+
+ :type end: :class:`datetime.datetime`
+ :param end: (Optional) The (exclusive) upper bound of the timestamp
+ range. If omitted, no upper bound is used.
+ """
+
+ def __init__(self, start: "datetime" | None = None, end: "datetime" | None = None):
+ self.start: "datetime" | None = start
+ self.end: "datetime" | None = end
+
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return other.start == self.start and other.end == self.end
+
+ def __ne__(self, other):
+ return not self == other
+
+ def _to_pb(self) -> data_v2_pb2.TimestampRange:
+ """Converts the :class:`TimestampRange` to a protobuf.
+
+ Returns: The converted current object.
+ """
+ return data_v2_pb2.TimestampRange(**self._to_dict())
+
+ def _to_dict(self) -> dict[str, int]:
+ """Converts the timestamp range to a dict representation."""
+ timestamp_range_kwargs = {}
+ if self.start is not None:
+ start_time = _microseconds_from_datetime(self.start) // 1000 * 1000
+ timestamp_range_kwargs["start_timestamp_micros"] = start_time
+ if self.end is not None:
+ end_time = _microseconds_from_datetime(self.end)
+ if end_time % 1000 != 0:
+ # if not a whole milisecond value, round up
+ end_time = end_time // 1000 * 1000 + 1000
+ timestamp_range_kwargs["end_timestamp_micros"] = end_time
+ return timestamp_range_kwargs
+
+ def __repr__(self) -> str:
+ return f"{self.__class__.__name__}(start={self.start}, end={self.end})"
+
+
+class TimestampRangeFilter(RowFilter):
+ """Row filter that limits cells to a range of time.
+
+ :type range_: :class:`TimestampRange`
+ :param range_: Range of time that cells should match against.
+ """
+
+ def __init__(self, start: "datetime" | None = None, end: "datetime" | None = None):
+ self.range_: TimestampRange = TimestampRange(start, end)
+
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return other.range_ == self.range_
+
+ def __ne__(self, other):
+ return not self == other
+
+ def _to_pb(self) -> data_v2_pb2.RowFilter:
+ """Converts the row filter to a protobuf.
+
+ First converts the ``range_`` on the current object to a protobuf and
+ then uses it in the ``timestamp_range_filter`` field.
+
+ Returns: The converted current object.
+ """
+ return data_v2_pb2.RowFilter(timestamp_range_filter=self.range_._to_pb())
+
+ def _to_dict(self) -> dict[str, Any]:
+ """Converts the row filter to a dict representation."""
+ return {"timestamp_range_filter": self.range_._to_dict()}
+
+ def __repr__(self) -> str:
+ return f"{self.__class__.__name__}(start={self.range_.start!r}, end={self.range_.end!r})"
+
+
+class ColumnRangeFilter(RowFilter):
+ """A row filter to restrict to a range of columns.
+
+ Both the start and end column can be included or excluded in the range.
+ By default, we include them both, but this can be changed with optional
+ flags.
+
+ :type family_id: str
+ :param family_id: The column family that contains the columns. Must
+ be of the form ``[_a-zA-Z0-9][-_.a-zA-Z0-9]*``.
+
+ :type start_qualifier: bytes
+ :param start_qualifier: The start of the range of columns. If no value is
+ used, the backend applies no upper bound to the
+ values.
+
+ :type end_qualifier: bytes
+ :param end_qualifier: The end of the range of columns. If no value is used,
+ the backend applies no upper bound to the values.
+
+ :type inclusive_start: bool
+ :param inclusive_start: Boolean indicating if the start column should be
+ included in the range (or excluded). Defaults
+ to :data:`True` if ``start_qualifier`` is passed and
+ no ``inclusive_start`` was given.
+
+ :type inclusive_end: bool
+ :param inclusive_end: Boolean indicating if the end column should be
+ included in the range (or excluded). Defaults
+ to :data:`True` if ``end_qualifier`` is passed and
+ no ``inclusive_end`` was given.
+
+ :raises: :class:`ValueError ` if ``inclusive_start``
+ is set but no ``start_qualifier`` is given or if ``inclusive_end``
+ is set but no ``end_qualifier`` is given
+ """
+
+ def __init__(
+ self,
+ family_id: str,
+ start_qualifier: bytes | None = None,
+ end_qualifier: bytes | None = None,
+ inclusive_start: bool | None = None,
+ inclusive_end: bool | None = None,
+ ):
+ if inclusive_start is None:
+ inclusive_start = True
+ elif start_qualifier is None:
+ raise ValueError(
+ "inclusive_start was specified but no start_qualifier was given."
+ )
+ if inclusive_end is None:
+ inclusive_end = True
+ elif end_qualifier is None:
+ raise ValueError(
+ "inclusive_end was specified but no end_qualifier was given."
+ )
+
+ self.family_id = family_id
+
+ self.start_qualifier = start_qualifier
+ self.inclusive_start = inclusive_start
+
+ self.end_qualifier = end_qualifier
+ self.inclusive_end = inclusive_end
+
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return (
+ other.family_id == self.family_id
+ and other.start_qualifier == self.start_qualifier
+ and other.end_qualifier == self.end_qualifier
+ and other.inclusive_start == self.inclusive_start
+ and other.inclusive_end == self.inclusive_end
+ )
+
+ def __ne__(self, other):
+ return not self == other
+
+ def _to_pb(self) -> data_v2_pb2.RowFilter:
+ """Converts the row filter to a protobuf.
+
+ First converts to a :class:`.data_v2_pb2.ColumnRange` and then uses it
+ in the ``column_range_filter`` field.
+
+ Returns: The converted current object.
+ """
+ column_range = data_v2_pb2.ColumnRange(**self._range_to_dict())
+ return data_v2_pb2.RowFilter(column_range_filter=column_range)
+
+ def _range_to_dict(self) -> dict[str, str | bytes]:
+ """Converts the column range range to a dict representation."""
+ column_range_kwargs: dict[str, str | bytes] = {}
+ column_range_kwargs["family_name"] = self.family_id
+ if self.start_qualifier is not None:
+ if self.inclusive_start:
+ key = "start_qualifier_closed"
+ else:
+ key = "start_qualifier_open"
+ column_range_kwargs[key] = _to_bytes(self.start_qualifier)
+ if self.end_qualifier is not None:
+ if self.inclusive_end:
+ key = "end_qualifier_closed"
+ else:
+ key = "end_qualifier_open"
+ column_range_kwargs[key] = _to_bytes(self.end_qualifier)
+ return column_range_kwargs
+
+ def _to_dict(self) -> dict[str, Any]:
+ """Converts the row filter to a dict representation."""
+ return {"column_range_filter": self._range_to_dict()}
+
+ def __repr__(self) -> str:
+ return f"{self.__class__.__name__}(family_id='{self.family_id}', start_qualifier={self.start_qualifier!r}, end_qualifier={self.end_qualifier!r}, inclusive_start={self.inclusive_start}, inclusive_end={self.inclusive_end})"
+
+
+class ValueRegexFilter(_RegexFilter):
+ """Row filter for a value regular expression.
+
+ The ``regex`` must be valid RE2 patterns. See Google's
+ `RE2 reference`_ for the accepted syntax.
+
+ .. _RE2 reference: https://github.com/google/re2/wiki/Syntax
+
+ .. note::
+
+ Special care need be used with the expression used. Since
+ each of these properties can contain arbitrary bytes, the ``\\C``
+ escape sequence must be used if a true wildcard is desired. The ``.``
+ character will not match the new line character ``\\n``, which may be
+ present in a binary value.
+
+ :type regex: bytes or str
+ :param regex: A regular expression (RE2) to match cells with values that
+ match this regex. String values will be encoded as ASCII.
+ """
+
+ def _to_dict(self) -> dict[str, bytes]:
+ """Converts the row filter to a dict representation."""
+ return {"value_regex_filter": self.regex}
+
+
+class LiteralValueFilter(ValueRegexFilter):
+ """Row filter for an exact value.
+
+
+ :type value: bytes or str or int
+ :param value:
+ a literal string, integer, or the equivalent bytes.
+ Integer values will be packed into signed 8-bytes.
+ """
+
+ def __init__(self, value: bytes | str | int):
+ if isinstance(value, int):
+ value = _PACK_I64(value)
+ elif isinstance(value, str):
+ value = value.encode("utf-8")
+ value = self._write_literal_regex(value)
+ super(LiteralValueFilter, self).__init__(value)
+
+ @staticmethod
+ def _write_literal_regex(input_bytes: bytes) -> bytes:
+ """
+ Escape re2 special characters from literal bytes.
+
+ Extracted from: re2 QuoteMeta:
+ https://github.com/google/re2/blob/70f66454c255080a54a8da806c52d1f618707f8a/re2/re2.cc#L456
+ """
+ result = bytearray()
+ for byte in input_bytes:
+ # If this is the part of a UTF8 or Latin1 character, we need \
+ # to copy this byte without escaping. Experimentally this is \
+ # what works correctly with the regexp library. \
+ utf8_latin1_check = (byte & 128) == 0
+ if (
+ (byte < ord("a") or byte > ord("z"))
+ and (byte < ord("A") or byte > ord("Z"))
+ and (byte < ord("0") or byte > ord("9"))
+ and byte != ord("_")
+ and utf8_latin1_check
+ ):
+ if byte == 0:
+ # Special handling for null chars.
+ # Note that this special handling is not strictly required for RE2,
+ # but this quoting is required for other regexp libraries such as
+ # PCRE.
+ # Can't use "\\0" since the next character might be a digit.
+ result.extend([ord("\\"), ord("x"), ord("0"), ord("0")])
+ continue
+ result.append(ord(b"\\"))
+ result.append(byte)
+ return bytes(result)
+
+ def __repr__(self) -> str:
+ return f"{self.__class__.__name__}(value={self.regex!r})"
+
+
+class ValueRangeFilter(RowFilter):
+ """A range of values to restrict to in a row filter.
+
+ Will only match cells that have values in this range.
+
+ Both the start and end value can be included or excluded in the range.
+ By default, we include them both, but this can be changed with optional
+ flags.
+
+ :type start_value: bytes
+ :param start_value: The start of the range of values. If no value is used,
+ the backend applies no lower bound to the values.
+
+ :type end_value: bytes
+ :param end_value: The end of the range of values. If no value is used,
+ the backend applies no upper bound to the values.
+
+ :type inclusive_start: bool
+ :param inclusive_start: Boolean indicating if the start value should be
+ included in the range (or excluded). Defaults
+ to :data:`True` if ``start_value`` is passed and
+ no ``inclusive_start`` was given.
+
+ :type inclusive_end: bool
+ :param inclusive_end: Boolean indicating if the end value should be
+ included in the range (or excluded). Defaults
+ to :data:`True` if ``end_value`` is passed and
+ no ``inclusive_end`` was given.
+
+ :raises: :class:`ValueError ` if ``inclusive_start``
+ is set but no ``start_value`` is given or if ``inclusive_end``
+ is set but no ``end_value`` is given
+ """
+
+ def __init__(
+ self,
+ start_value: bytes | int | None = None,
+ end_value: bytes | int | None = None,
+ inclusive_start: bool | None = None,
+ inclusive_end: bool | None = None,
+ ):
+ if inclusive_start is None:
+ inclusive_start = True
+ elif start_value is None:
+ raise ValueError(
+ "inclusive_start was specified but no start_value was given."
+ )
+ if inclusive_end is None:
+ inclusive_end = True
+ elif end_value is None:
+ raise ValueError(
+ "inclusive_end was specified but no end_qualifier was given."
+ )
+ if isinstance(start_value, int):
+ start_value = _PACK_I64(start_value)
+ self.start_value = start_value
+ self.inclusive_start = inclusive_start
+
+ if isinstance(end_value, int):
+ end_value = _PACK_I64(end_value)
+ self.end_value = end_value
+ self.inclusive_end = inclusive_end
+
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return (
+ other.start_value == self.start_value
+ and other.end_value == self.end_value
+ and other.inclusive_start == self.inclusive_start
+ and other.inclusive_end == self.inclusive_end
+ )
+
+ def __ne__(self, other):
+ return not self == other
+
+ def _to_pb(self) -> data_v2_pb2.RowFilter:
+ """Converts the row filter to a protobuf.
+
+ First converts to a :class:`.data_v2_pb2.ValueRange` and then uses
+ it to create a row filter protobuf.
+
+ Returns: The converted current object.
+ """
+ value_range = data_v2_pb2.ValueRange(**self._range_to_dict())
+ return data_v2_pb2.RowFilter(value_range_filter=value_range)
+
+ def _range_to_dict(self) -> dict[str, bytes]:
+ """Converts the value range range to a dict representation."""
+ value_range_kwargs = {}
+ if self.start_value is not None:
+ if self.inclusive_start:
+ key = "start_value_closed"
+ else:
+ key = "start_value_open"
+ value_range_kwargs[key] = _to_bytes(self.start_value)
+ if self.end_value is not None:
+ if self.inclusive_end:
+ key = "end_value_closed"
+ else:
+ key = "end_value_open"
+ value_range_kwargs[key] = _to_bytes(self.end_value)
+ return value_range_kwargs
+
+ def _to_dict(self) -> dict[str, Any]:
+ """Converts the row filter to a dict representation."""
+ return {"value_range_filter": self._range_to_dict()}
+
+ def __repr__(self) -> str:
+ return f"{self.__class__.__name__}(start_value={self.start_value!r}, end_value={self.end_value!r}, inclusive_start={self.inclusive_start}, inclusive_end={self.inclusive_end})"
+
+
+class _CellCountFilter(RowFilter, ABC):
+ """Row filter that uses an integer count of cells.
+
+ The cell count is used as an offset or a limit for the number
+ of results returned.
+
+ :type num_cells: int
+ :param num_cells: An integer count / offset / limit.
+ """
+
+ def __init__(self, num_cells: int):
+ self.num_cells = num_cells
+
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return other.num_cells == self.num_cells
+
+ def __ne__(self, other):
+ return not self == other
+
+ def __repr__(self) -> str:
+ return f"{self.__class__.__name__}(num_cells={self.num_cells})"
+
+
+class CellsRowOffsetFilter(_CellCountFilter):
+ """Row filter to skip cells in a row.
+
+ :type num_cells: int
+ :param num_cells: Skips the first N cells of the row.
+ """
+
+ def _to_dict(self) -> dict[str, int]:
+ """Converts the row filter to a dict representation."""
+ return {"cells_per_row_offset_filter": self.num_cells}
+
+
+class CellsRowLimitFilter(_CellCountFilter):
+ """Row filter to limit cells in a row.
+
+ :type num_cells: int
+ :param num_cells: Matches only the first N cells of the row.
+ """
+
+ def _to_dict(self) -> dict[str, int]:
+ """Converts the row filter to a dict representation."""
+ return {"cells_per_row_limit_filter": self.num_cells}
+
+
+class CellsColumnLimitFilter(_CellCountFilter):
+ """Row filter to limit cells in a column.
+
+ :type num_cells: int
+ :param num_cells: Matches only the most recent N cells within each column.
+ This filters a (family name, column) pair, based on
+ timestamps of each cell.
+ """
+
+ def _to_dict(self) -> dict[str, int]:
+ """Converts the row filter to a dict representation."""
+ return {"cells_per_column_limit_filter": self.num_cells}
+
+
+class StripValueTransformerFilter(_BoolFilter):
+ """Row filter that transforms cells into empty string (0 bytes).
+
+ :type flag: bool
+ :param flag: If :data:`True`, replaces each cell's value with the empty
+ string. As the name indicates, this is more useful as a
+ transformer than a generic query / filter.
+ """
+
+ def _to_dict(self) -> dict[str, Any]:
+ """Converts the row filter to a dict representation."""
+ return {"strip_value_transformer": self.flag}
+
+
+class ApplyLabelFilter(RowFilter):
+ """Filter to apply labels to cells.
+
+ Intended to be used as an intermediate filter on a pre-existing filtered
+ result set. This way if two sets are combined, the label can tell where
+ the cell(s) originated.This allows the client to determine which results
+ were produced from which part of the filter.
+
+ .. note::
+
+ Due to a technical limitation of the backend, it is not currently
+ possible to apply multiple labels to a cell.
+
+ :type label: str
+ :param label: Label to apply to cells in the output row. Values must be
+ at most 15 characters long, and match the pattern
+ ``[a-z0-9\\-]+``.
+ """
+
+ def __init__(self, label: str):
+ self.label = label
+
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return other.label == self.label
+
+ def __ne__(self, other):
+ return not self == other
+
+ def _to_dict(self) -> dict[str, str]:
+ """Converts the row filter to a dict representation."""
+ return {"apply_label_transformer": self.label}
+
+ def __repr__(self) -> str:
+ return f"{self.__class__.__name__}(label={self.label})"
+
+
+class _FilterCombination(RowFilter, Sequence[RowFilter], ABC):
+ """Chain of row filters.
+
+ Sends rows through several filters in sequence. The filters are "chained"
+ together to process a row. After the first filter is applied, the second
+ is applied to the filtered output and so on for subsequent filters.
+
+ :type filters: list
+ :param filters: List of :class:`RowFilter`
+ """
+
+ def __init__(self, filters: list[RowFilter] | None = None):
+ if filters is None:
+ filters = []
+ self.filters: list[RowFilter] = filters
+
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return other.filters == self.filters
+
+ def __ne__(self, other):
+ return not self == other
+
+ def __len__(self) -> int:
+ return len(self.filters)
+
+ @overload
+ def __getitem__(self, index: int) -> RowFilter:
+ # overload signature for type checking
+ pass
+
+ @overload
+ def __getitem__(self, index: slice) -> list[RowFilter]:
+ # overload signature for type checking
+ pass
+
+ def __getitem__(self, index):
+ return self.filters[index]
+
+ def __repr__(self) -> str:
+ return f"{self.__class__.__name__}(filters={self.filters})"
+
+ def __str__(self) -> str:
+ """
+ Returns a string representation of the filter chain.
+
+ Adds line breaks between each sub-filter for readability.
+ """
+ output = [f"{self.__class__.__name__}(["]
+ for filter_ in self.filters:
+ filter_lines = f"{filter_},".splitlines()
+ output.extend([f" {line}" for line in filter_lines])
+ output.append("])")
+ return "\n".join(output)
+
+
+class RowFilterChain(_FilterCombination):
+ """Chain of row filters.
+
+ Sends rows through several filters in sequence. The filters are "chained"
+ together to process a row. After the first filter is applied, the second
+ is applied to the filtered output and so on for subsequent filters.
+
+ :type filters: list
+ :param filters: List of :class:`RowFilter`
+ """
+
+ def _to_pb(self) -> data_v2_pb2.RowFilter:
+ """Converts the row filter to a protobuf.
+
+ Returns: The converted current object.
+ """
+ chain = data_v2_pb2.RowFilter.Chain(
+ filters=[row_filter._to_pb() for row_filter in self.filters]
+ )
+ return data_v2_pb2.RowFilter(chain=chain)
+
+ def _to_dict(self) -> dict[str, Any]:
+ """Converts the row filter to a dict representation."""
+ return {"chain": {"filters": [f._to_dict() for f in self.filters]}}
+
+
+class RowFilterUnion(_FilterCombination):
+ """Union of row filters.
+
+ Sends rows through several filters simultaneously, then
+ merges / interleaves all the filtered results together.
+
+ If multiple cells are produced with the same column and timestamp,
+ they will all appear in the output row in an unspecified mutual order.
+
+ :type filters: list
+ :param filters: List of :class:`RowFilter`
+ """
+
+ def _to_pb(self) -> data_v2_pb2.RowFilter:
+ """Converts the row filter to a protobuf.
+
+ Returns: The converted current object.
+ """
+ interleave = data_v2_pb2.RowFilter.Interleave(
+ filters=[row_filter._to_pb() for row_filter in self.filters]
+ )
+ return data_v2_pb2.RowFilter(interleave=interleave)
+
+ def _to_dict(self) -> dict[str, Any]:
+ """Converts the row filter to a dict representation."""
+ return {"interleave": {"filters": [f._to_dict() for f in self.filters]}}
+
+
+class ConditionalRowFilter(RowFilter):
+ """Conditional row filter which exhibits ternary behavior.
+
+ Executes one of two filters based on another filter. If the ``predicate_filter``
+ returns any cells in the row, then ``true_filter`` is executed. If not,
+ then ``false_filter`` is executed.
+
+ .. note::
+
+ The ``predicate_filter`` does not execute atomically with the true and false
+ filters, which may lead to inconsistent or unexpected results.
+
+ Additionally, executing a :class:`ConditionalRowFilter` has poor
+ performance on the server, especially when ``false_filter`` is set.
+
+ :type predicate_filter: :class:`RowFilter`
+ :param predicate_filter: The filter to condition on before executing the
+ true/false filters.
+
+ :type true_filter: :class:`RowFilter`
+ :param true_filter: (Optional) The filter to execute if there are any cells
+ matching ``predicate_filter``. If not provided, no results
+ will be returned in the true case.
+
+ :type false_filter: :class:`RowFilter`
+ :param false_filter: (Optional) The filter to execute if there are no cells
+ matching ``predicate_filter``. If not provided, no results
+ will be returned in the false case.
+ """
+
+ def __init__(
+ self,
+ predicate_filter: RowFilter,
+ true_filter: RowFilter | None = None,
+ false_filter: RowFilter | None = None,
+ ):
+ self.predicate_filter = predicate_filter
+ self.true_filter = true_filter
+ self.false_filter = false_filter
+
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return (
+ other.predicate_filter == self.predicate_filter
+ and other.true_filter == self.true_filter
+ and other.false_filter == self.false_filter
+ )
+
+ def __ne__(self, other):
+ return not self == other
+
+ def _to_pb(self) -> data_v2_pb2.RowFilter:
+ """Converts the row filter to a protobuf.
+
+ Returns: The converted current object.
+ """
+ condition_kwargs = {"predicate_filter": self.predicate_filter._to_pb()}
+ if self.true_filter is not None:
+ condition_kwargs["true_filter"] = self.true_filter._to_pb()
+ if self.false_filter is not None:
+ condition_kwargs["false_filter"] = self.false_filter._to_pb()
+ condition = data_v2_pb2.RowFilter.Condition(**condition_kwargs)
+ return data_v2_pb2.RowFilter(condition=condition)
+
+ def _condition_to_dict(self) -> dict[str, Any]:
+ """Converts the condition to a dict representation."""
+ condition_kwargs = {"predicate_filter": self.predicate_filter._to_dict()}
+ if self.true_filter is not None:
+ condition_kwargs["true_filter"] = self.true_filter._to_dict()
+ if self.false_filter is not None:
+ condition_kwargs["false_filter"] = self.false_filter._to_dict()
+ return condition_kwargs
+
+ def _to_dict(self) -> dict[str, Any]:
+ """Converts the row filter to a dict representation."""
+ return {"condition": self._condition_to_dict()}
+
+ def __repr__(self) -> str:
+ return f"{self.__class__.__name__}(predicate_filter={self.predicate_filter!r}, true_filter={self.true_filter!r}, false_filter={self.false_filter!r})"
+
+ def __str__(self) -> str:
+ output = [f"{self.__class__.__name__}("]
+ for filter_type in ("predicate_filter", "true_filter", "false_filter"):
+ filter_ = getattr(self, filter_type)
+ if filter_ is None:
+ continue
+ # add the new filter set, adding indentations for readability
+ filter_lines = f"{filter_type}={filter_},".splitlines()
+ output.extend(f" {line}" for line in filter_lines)
+ output.append(")")
+ return "\n".join(output)
diff --git a/google/cloud/bigtable/gapic_version.py b/google/cloud/bigtable/gapic_version.py
new file mode 100644
index 000000000..a105a8349
--- /dev/null
+++ b/google/cloud/bigtable/gapic_version.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+# Copyright 2022 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.
+#
+__version__ = "2.35.0" # {x-release-please-version}
diff --git a/google/cloud/bigtable/helpers.py b/google/cloud/bigtable/helpers.py
new file mode 100644
index 000000000..78af43089
--- /dev/null
+++ b/google/cloud/bigtable/helpers.py
@@ -0,0 +1,31 @@
+# Copyright 2024 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.
+
+from typing import TypeVar, Iterable, Generator, Tuple
+
+from itertools import islice
+
+T = TypeVar("T")
+
+
+# batched landed in standard library in Python 3.11.
+def batched(iterable: Iterable[T], n) -> Generator[Tuple[T, ...], None, None]:
+ # batched('ABCDEFG', 3) â ABC DEF G
+ if n < 1:
+ raise ValueError("n must be at least one")
+ it = iter(iterable)
+ batch = tuple(islice(it, n))
+ while batch:
+ yield batch
+ batch = tuple(islice(it, n))
diff --git a/google/cloud/bigtable/instance.py b/google/cloud/bigtable/instance.py
index 6d092cefd..23fb1c95d 100644
--- a/google/cloud/bigtable/instance.py
+++ b/google/cloud/bigtable/instance.py
@@ -32,6 +32,7 @@
import warnings
+
_INSTANCE_NAME_RE = re.compile(
r"^projects/(?P[^/]+)/" r"instances/(?P[a-z][-a-z0-9]*)$"
)
diff --git a/google/cloud/bigtable/py.typed b/google/cloud/bigtable/py.typed
index 7bd4705d4..889d34043 100644
--- a/google/cloud/bigtable/py.typed
+++ b/google/cloud/bigtable/py.typed
@@ -1,2 +1,2 @@
-# Marker file for PEP 561.
-# The google-cloud-bigtable package uses inline types.
+# Marker file for PEP 561.
+# The google-cloud-bigtable package uses inline types.
diff --git a/google/cloud/bigtable/row.py b/google/cloud/bigtable/row.py
index 9127a1aae..752458a08 100644
--- a/google/cloud/bigtable/row.py
+++ b/google/cloud/bigtable/row.py
@@ -28,6 +28,15 @@
MAX_MUTATIONS = 100000
"""The maximum number of mutations that a row can accumulate."""
+_MISSING_COLUMN_FAMILY = "Column family {} is not among the cells stored in this row."
+_MISSING_COLUMN = (
+ "Column {} is not among the cells stored in this row in the column family {}."
+)
+_MISSING_INDEX = (
+ "Index {!r} is not valid for the cells stored in this row for column {} "
+ "in the column family {}. There are {} such cells."
+)
+
class Row(object):
"""Base representation of a Google Cloud Bigtable Row.
@@ -1013,3 +1022,246 @@ def _parse_family_pb(family_pb):
cells.append(val_pair)
return family_pb.name, result
+
+
+class PartialRowData(object):
+ """Representation of partial row in a Google Cloud Bigtable Table.
+
+ These are expected to be updated directly from a
+ :class:`._generated.bigtable_service_messages_pb2.ReadRowsResponse`
+
+ :type row_key: bytes
+ :param row_key: The key for the row holding the (partial) data.
+ """
+
+ def __init__(self, row_key):
+ self._row_key = row_key
+ self._cells = {}
+
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return other._row_key == self._row_key and other._cells == self._cells
+
+ def __ne__(self, other):
+ return not self == other
+
+ def to_dict(self):
+ """Convert the cells to a dictionary.
+
+ This is intended to be used with HappyBase, so the column family and
+ column qualiers are combined (with ``:``).
+
+ :rtype: dict
+ :returns: Dictionary containing all the data in the cells of this row.
+ """
+ result = {}
+ for column_family_id, columns in self._cells.items():
+ for column_qual, cells in columns.items():
+ key = _to_bytes(column_family_id) + b":" + _to_bytes(column_qual)
+ result[key] = cells
+ return result
+
+ @property
+ def cells(self):
+ """Property returning all the cells accumulated on this partial row.
+
+ For example:
+
+ .. literalinclude:: snippets_table.py
+ :start-after: [START bigtable_api_row_data_cells]
+ :end-before: [END bigtable_api_row_data_cells]
+ :dedent: 4
+
+ :rtype: dict
+ :returns: Dictionary of the :class:`Cell` objects accumulated. This
+ dictionary has two-levels of keys (first for column families
+ and second for column names/qualifiers within a family). For
+ a given column, a list of :class:`Cell` objects is stored.
+ """
+ return self._cells
+
+ @property
+ def row_key(self):
+ """Getter for the current (partial) row's key.
+
+ :rtype: bytes
+ :returns: The current (partial) row's key.
+ """
+ return self._row_key
+
+ def find_cells(self, column_family_id, column):
+ """Get a time series of cells stored on this instance.
+
+ For example:
+
+ .. literalinclude:: snippets_table.py
+ :start-after: [START bigtable_api_row_find_cells]
+ :end-before: [END bigtable_api_row_find_cells]
+ :dedent: 4
+
+ Args:
+ column_family_id (str): The ID of the column family. Must be of the
+ form ``[_a-zA-Z0-9][-_.a-zA-Z0-9]*``.
+ column (bytes): The column within the column family where the cells
+ are located.
+
+ Returns:
+ List[~google.cloud.bigtable.row_data.Cell]: The cells stored in the
+ specified column.
+
+ Raises:
+ KeyError: If ``column_family_id`` is not among the cells stored
+ in this row.
+ KeyError: If ``column`` is not among the cells stored in this row
+ for the given ``column_family_id``.
+ """
+ try:
+ column_family = self._cells[column_family_id]
+ except KeyError:
+ raise KeyError(_MISSING_COLUMN_FAMILY.format(column_family_id))
+
+ try:
+ cells = column_family[column]
+ except KeyError:
+ raise KeyError(_MISSING_COLUMN.format(column, column_family_id))
+
+ return cells
+
+ def cell_value(self, column_family_id, column, index=0):
+ """Get a single cell value stored on this instance.
+
+ For example:
+
+ .. literalinclude:: snippets_table.py
+ :start-after: [START bigtable_api_row_cell_value]
+ :end-before: [END bigtable_api_row_cell_value]
+ :dedent: 4
+
+ Args:
+ column_family_id (str): The ID of the column family. Must be of the
+ form ``[_a-zA-Z0-9][-_.a-zA-Z0-9]*``.
+ column (bytes): The column within the column family where the cell
+ is located.
+ index (Optional[int]): The offset within the series of values. If
+ not specified, will return the first cell.
+
+ Returns:
+ ~google.cloud.bigtable.row_data.Cell value: The cell value stored
+ in the specified column and specified index.
+
+ Raises:
+ KeyError: If ``column_family_id`` is not among the cells stored
+ in this row.
+ KeyError: If ``column`` is not among the cells stored in this row
+ for the given ``column_family_id``.
+ IndexError: If ``index`` cannot be found within the cells stored
+ in this row for the given ``column_family_id``, ``column``
+ pair.
+ """
+ cells = self.find_cells(column_family_id, column)
+
+ try:
+ cell = cells[index]
+ except (TypeError, IndexError):
+ num_cells = len(cells)
+ msg = _MISSING_INDEX.format(index, column, column_family_id, num_cells)
+ raise IndexError(msg)
+
+ return cell.value
+
+ def cell_values(self, column_family_id, column, max_count=None):
+ """Get a time series of cells stored on this instance.
+
+ For example:
+
+ .. literalinclude:: snippets_table.py
+ :start-after: [START bigtable_api_row_cell_values]
+ :end-before: [END bigtable_api_row_cell_values]
+ :dedent: 4
+
+ Args:
+ column_family_id (str): The ID of the column family. Must be of the
+ form ``[_a-zA-Z0-9][-_.a-zA-Z0-9]*``.
+ column (bytes): The column within the column family where the cells
+ are located.
+ max_count (int): The maximum number of cells to use.
+
+ Returns:
+ A generator which provides: cell.value, cell.timestamp_micros
+ for each cell in the list of cells
+
+ Raises:
+ KeyError: If ``column_family_id`` is not among the cells stored
+ in this row.
+ KeyError: If ``column`` is not among the cells stored in this row
+ for the given ``column_family_id``.
+ """
+ cells = self.find_cells(column_family_id, column)
+ if max_count is None:
+ max_count = len(cells)
+
+ for index, cell in enumerate(cells):
+ if index == max_count:
+ break
+
+ yield cell.value, cell.timestamp_micros
+
+
+class Cell(object):
+ """Representation of a Google Cloud Bigtable Cell.
+
+ :type value: bytes
+ :param value: The value stored in the cell.
+
+ :type timestamp_micros: int
+ :param timestamp_micros: The timestamp_micros when the cell was stored.
+
+ :type labels: list
+ :param labels: (Optional) List of strings. Labels applied to the cell.
+ """
+
+ def __init__(self, value, timestamp_micros, labels=None):
+ self.value = value
+ self.timestamp_micros = timestamp_micros
+ self.labels = list(labels) if labels is not None else []
+
+ @classmethod
+ def from_pb(cls, cell_pb):
+ """Create a new cell from a Cell protobuf.
+
+ :type cell_pb: :class:`._generated.data_pb2.Cell`
+ :param cell_pb: The protobuf to convert.
+
+ :rtype: :class:`Cell`
+ :returns: The cell corresponding to the protobuf.
+ """
+ if cell_pb.labels:
+ return cls(cell_pb.value, cell_pb.timestamp_micros, labels=cell_pb.labels)
+ else:
+ return cls(cell_pb.value, cell_pb.timestamp_micros)
+
+ @property
+ def timestamp(self):
+ return _datetime_from_microseconds(self.timestamp_micros)
+
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return (
+ other.value == self.value
+ and other.timestamp_micros == self.timestamp_micros
+ and other.labels == self.labels
+ )
+
+ def __ne__(self, other):
+ return not self == other
+
+ def __repr__(self):
+ return "<{name} value={value!r} timestamp={timestamp}>".format(
+ name=self.__class__.__name__, value=self.value, timestamp=self.timestamp
+ )
+
+
+class InvalidChunk(RuntimeError):
+ """Exception raised to invalid chunk data from back-end."""
diff --git a/google/cloud/bigtable/row_data.py b/google/cloud/bigtable/row_data.py
index 0c1565737..e11379108 100644
--- a/google/cloud/bigtable/row_data.py
+++ b/google/cloud/bigtable/row_data.py
@@ -18,104 +18,25 @@
import copy
import grpc # type: ignore
-
+import warnings
from google.api_core import exceptions
from google.api_core import retry
-from google.cloud._helpers import _datetime_from_microseconds # type: ignore
from google.cloud._helpers import _to_bytes # type: ignore
+
+from google.cloud.bigtable.row_merger import _RowMerger, _State
from google.cloud.bigtable_v2.types import bigtable as data_messages_v2_pb2
from google.cloud.bigtable_v2.types import data as data_v2_pb2
+from google.cloud.bigtable.row import Cell, InvalidChunk, PartialRowData
-_MISSING_COLUMN_FAMILY = "Column family {} is not among the cells stored in this row."
-_MISSING_COLUMN = (
- "Column {} is not among the cells stored in this row in the " "column family {}."
-)
-_MISSING_INDEX = (
- "Index {!r} is not valid for the cells stored in this row for column {} "
- "in the column family {}. There are {} such cells."
-)
-
-
-class Cell(object):
- """Representation of a Google Cloud Bigtable Cell.
- :type value: bytes
- :param value: The value stored in the cell.
-
- :type timestamp_micros: int
- :param timestamp_micros: The timestamp_micros when the cell was stored.
-
- :type labels: list
- :param labels: (Optional) List of strings. Labels applied to the cell.
- """
-
- def __init__(self, value, timestamp_micros, labels=None):
- self.value = value
- self.timestamp_micros = timestamp_micros
- self.labels = list(labels) if labels is not None else []
-
- @classmethod
- def from_pb(cls, cell_pb):
- """Create a new cell from a Cell protobuf.
-
- :type cell_pb: :class:`._generated.data_pb2.Cell`
- :param cell_pb: The protobuf to convert.
-
- :rtype: :class:`Cell`
- :returns: The cell corresponding to the protobuf.
- """
- if cell_pb.labels:
- return cls(cell_pb.value, cell_pb.timestamp_micros, labels=cell_pb.labels)
- else:
- return cls(cell_pb.value, cell_pb.timestamp_micros)
-
- @property
- def timestamp(self):
- return _datetime_from_microseconds(self.timestamp_micros)
-
- def __eq__(self, other):
- if not isinstance(other, self.__class__):
- return NotImplemented
- return (
- other.value == self.value
- and other.timestamp_micros == self.timestamp_micros
- and other.labels == self.labels
- )
-
- def __ne__(self, other):
- return not self == other
-
- def __repr__(self):
- return "<{name} value={value!r} timestamp={timestamp}>".format(
- name=self.__class__.__name__, value=self.value, timestamp=self.timestamp
- )
+# Some classes need to be re-exported here to keep backwards
+# compatibility. Those classes were moved to row_merger, but we dont want to
+# break enduser's imports. This hack, ensures they don't get marked as unused.
+_ = (Cell, InvalidChunk, PartialRowData)
-class PartialCellData(object):
- """Representation of partial cell in a Google Cloud Bigtable Table.
-
- These are expected to be updated directly from a
- :class:`._generated.bigtable_service_messages_pb2.ReadRowsResponse`
-
- :type row_key: bytes
- :param row_key: The key for the row holding the (partial) cell.
-
- :type family_name: str
- :param family_name: The family name of the (partial) cell.
-
- :type qualifier: bytes
- :param qualifier: The column qualifier of the (partial) cell.
-
- :type timestamp_micros: int
- :param timestamp_micros: The timestamp (in microsecods) of the
- (partial) cell.
-
- :type labels: list of str
- :param labels: labels assigned to the (partial) cell
-
- :type value: bytes
- :param value: The (accumulated) value of the (partial) cell.
- """
+class PartialCellData(object): # pragma: NO COVER
+ """This class is no longer used and will be removed in the future"""
def __init__(
self, row_key, family_name, qualifier, timestamp_micros, labels=(), value=b""
@@ -128,214 +49,43 @@ def __init__(
self.value = value
def append_value(self, value):
- """Append bytes from a new chunk to value.
-
- :type value: bytes
- :param value: bytes to append
- """
self.value += value
-class PartialRowData(object):
- """Representation of partial row in a Google Cloud Bigtable Table.
-
- These are expected to be updated directly from a
- :class:`._generated.bigtable_service_messages_pb2.ReadRowsResponse`
-
- :type row_key: bytes
- :param row_key: The key for the row holding the (partial) data.
- """
-
- def __init__(self, row_key):
- self._row_key = row_key
- self._cells = {}
-
- def __eq__(self, other):
- if not isinstance(other, self.__class__):
- return NotImplemented
- return other._row_key == self._row_key and other._cells == self._cells
-
- def __ne__(self, other):
- return not self == other
-
- def to_dict(self):
- """Convert the cells to a dictionary.
-
- This is intended to be used with HappyBase, so the column family and
- column qualiers are combined (with ``:``).
-
- :rtype: dict
- :returns: Dictionary containing all the data in the cells of this row.
- """
- result = {}
- for column_family_id, columns in self._cells.items():
- for column_qual, cells in columns.items():
- key = _to_bytes(column_family_id) + b":" + _to_bytes(column_qual)
- result[key] = cells
- return result
-
- @property
- def cells(self):
- """Property returning all the cells accumulated on this partial row.
-
- For example:
-
- .. literalinclude:: snippets_table.py
- :start-after: [START bigtable_api_row_data_cells]
- :end-before: [END bigtable_api_row_data_cells]
- :dedent: 4
-
- :rtype: dict
- :returns: Dictionary of the :class:`Cell` objects accumulated. This
- dictionary has two-levels of keys (first for column families
- and second for column names/qualifiers within a family). For
- a given column, a list of :class:`Cell` objects is stored.
- """
- return self._cells
-
- @property
- def row_key(self):
- """Getter for the current (partial) row's key.
-
- :rtype: bytes
- :returns: The current (partial) row's key.
- """
- return self._row_key
-
- def find_cells(self, column_family_id, column):
- """Get a time series of cells stored on this instance.
-
- For example:
-
- .. literalinclude:: snippets_table.py
- :start-after: [START bigtable_api_row_find_cells]
- :end-before: [END bigtable_api_row_find_cells]
- :dedent: 4
-
- Args:
- column_family_id (str): The ID of the column family. Must be of the
- form ``[_a-zA-Z0-9][-_.a-zA-Z0-9]*``.
- column (bytes): The column within the column family where the cells
- are located.
-
- Returns:
- List[~google.cloud.bigtable.row_data.Cell]: The cells stored in the
- specified column.
-
- Raises:
- KeyError: If ``column_family_id`` is not among the cells stored
- in this row.
- KeyError: If ``column`` is not among the cells stored in this row
- for the given ``column_family_id``.
- """
- try:
- column_family = self._cells[column_family_id]
- except KeyError:
- raise KeyError(_MISSING_COLUMN_FAMILY.format(column_family_id))
-
- try:
- cells = column_family[column]
- except KeyError:
- raise KeyError(_MISSING_COLUMN.format(column, column_family_id))
-
- return cells
-
- def cell_value(self, column_family_id, column, index=0):
- """Get a single cell value stored on this instance.
-
- For example:
-
- .. literalinclude:: snippets_table.py
- :start-after: [START bigtable_api_row_cell_value]
- :end-before: [END bigtable_api_row_cell_value]
- :dedent: 4
-
- Args:
- column_family_id (str): The ID of the column family. Must be of the
- form ``[_a-zA-Z0-9][-_.a-zA-Z0-9]*``.
- column (bytes): The column within the column family where the cell
- is located.
- index (Optional[int]): The offset within the series of values. If
- not specified, will return the first cell.
-
- Returns:
- ~google.cloud.bigtable.row_data.Cell value: The cell value stored
- in the specified column and specified index.
-
- Raises:
- KeyError: If ``column_family_id`` is not among the cells stored
- in this row.
- KeyError: If ``column`` is not among the cells stored in this row
- for the given ``column_family_id``.
- IndexError: If ``index`` cannot be found within the cells stored
- in this row for the given ``column_family_id``, ``column``
- pair.
- """
- cells = self.find_cells(column_family_id, column)
-
- try:
- cell = cells[index]
- except (TypeError, IndexError):
- num_cells = len(cells)
- msg = _MISSING_INDEX.format(index, column, column_family_id, num_cells)
- raise IndexError(msg)
-
- return cell.value
-
- def cell_values(self, column_family_id, column, max_count=None):
- """Get a time series of cells stored on this instance.
-
- For example:
-
- .. literalinclude:: snippets_table.py
- :start-after: [START bigtable_api_row_cell_values]
- :end-before: [END bigtable_api_row_cell_values]
- :dedent: 4
-
- Args:
- column_family_id (str): The ID of the column family. Must be of the
- form ``[_a-zA-Z0-9][-_.a-zA-Z0-9]*``.
- column (bytes): The column within the column family where the cells
- are located.
- max_count (int): The maximum number of cells to use.
-
- Returns:
- A generator which provides: cell.value, cell.timestamp_micros
- for each cell in the list of cells
-
- Raises:
- KeyError: If ``column_family_id`` is not among the cells stored
- in this row.
- KeyError: If ``column`` is not among the cells stored in this row
- for the given ``column_family_id``.
- """
- cells = self.find_cells(column_family_id, column)
- if max_count is None:
- max_count = len(cells)
-
- for index, cell in enumerate(cells):
- if index == max_count:
- break
-
- yield cell.value, cell.timestamp_micros
-
-
class InvalidReadRowsResponse(RuntimeError):
"""Exception raised to invalid response data from back-end."""
-class InvalidChunk(RuntimeError):
- """Exception raised to invalid chunk data from back-end."""
-
-
class InvalidRetryRequest(RuntimeError):
"""Exception raised when retry request is invalid."""
+RETRYABLE_INTERNAL_ERROR_MESSAGES = (
+ "rst_stream",
+ "rst stream",
+ "received unexpected eos on data frame from server",
+)
+"""Internal error messages that can be retried during read row and mutation."""
+
+
+def _retriable_internal_server_error(exc):
+ """
+ Return True if the internal server error is retriable.
+ """
+ return isinstance(exc, exceptions.InternalServerError) and any(
+ retryable_message in exc.message.lower()
+ for retryable_message in RETRYABLE_INTERNAL_ERROR_MESSAGES
+ )
+
+
def _retry_read_rows_exception(exc):
+ """Return True if the exception is retriable for read row requests."""
if isinstance(exc, grpc.RpcError):
exc = exceptions.from_grpc_error(exc)
- return isinstance(exc, (exceptions.ServiceUnavailable, exceptions.DeadlineExceeded))
+
+ return _retriable_internal_server_error(exc) or isinstance(
+ exc, (exceptions.ServiceUnavailable, exceptions.DeadlineExceeded)
+ )
DEFAULT_RETRY_READ_ROWS = retry.Retry(
@@ -393,14 +143,7 @@ class PartialRowsData(object):
def __init__(self, read_method, request, retry=DEFAULT_RETRY_READ_ROWS):
# Counter for rows returned to the user
self._counter = 0
- # In-progress row, unset until first response, after commit/reset
- self._row = None
- # Last complete row, unset until first commit
- self._previous_row = None
- # In-progress cell, unset until first response, after completion
- self._cell = None
- # Last complete cell, unset until first completion, after new row
- self._previous_cell = None
+ self._row_merger = _RowMerger()
# May be cached from previous response
self.last_scanned_row_key = None
@@ -414,23 +157,40 @@ def __init__(self, read_method, request, retry=DEFAULT_RETRY_READ_ROWS):
# Otherwise there is a risk of entering an infinite loop that resets
# the timeout counter just before it being triggered. The increment
# by 1 second here is customary but should not be much less than that.
- self.response_iterator = read_method(request, timeout=self.retry._deadline + 1)
+ self.response_iterator = read_method(
+ request, timeout=self.retry._deadline + 1, retry=self.retry
+ )
self.rows = {}
- self._state = self.STATE_NEW_ROW
# Flag to stop iteration, for any reason not related to self.retry()
self._cancelled = False
@property
- def state(self):
- """State machine state.
-
- :rtype: str
- :returns: name of state corresponding to current row / chunk
- processing.
+ def state(self): # pragma: NO COVER
"""
- return self.read_states[self._state]
+ DEPRECATED: this property is deprecated and will be removed in the
+ future.
+ """
+ warnings.warn(
+ "`PartialRowsData#state()` is deprecated and will be removed in the future",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+
+ # Best effort: try to map internal RowMerger states to old strings for
+ # backwards compatibility
+ internal_state = self._row_merger.state
+ if internal_state == _State.ROW_START:
+ return self.NEW_ROW
+ # note: _State.CELL_START, _State.CELL_COMPLETE are transient states
+ # and will not be visible in between chunks
+ elif internal_state == _State.CELL_IN_PROGRESS:
+ return self.CELL_IN_PROGRESS
+ elif internal_state == _State.ROW_COMPLETE:
+ return self.NEW_ROW
+ else:
+ raise RuntimeError("unexpected internal state: " + self._)
def cancel(self):
"""Cancels the iterator, closing the stream."""
@@ -466,6 +226,7 @@ def _on_error(self, exc):
if self.last_scanned_row_key:
retry_request = self._create_retry_request()
+ self._row_merger = _RowMerger(self._row_merger.last_seen_row_key)
self.response_iterator = self.read_method(retry_request)
def _read_next(self):
@@ -474,7 +235,11 @@ def _read_next(self):
def _read_next_response(self):
"""Helper for :meth:`__iter__`."""
- return self.retry(self._read_next, on_error=self._on_error)()
+ resp_protoplus = self.retry(self._read_next, on_error=self._on_error)()
+ # unwrap the underlying protobuf, there is a significant amount of
+ # overhead that protoplus imposes for very little gain. The protos
+ # are not user visible, so we just use the raw protos for merging.
+ return data_messages_v2_pb2.ReadRowsResponse.pb(resp_protoplus)
def __iter__(self):
"""Consume the ``ReadRowsResponse`` s from the stream.
@@ -487,124 +252,23 @@ def __iter__(self):
try:
response = self._read_next_response()
except StopIteration:
- if self.state != self.NEW_ROW:
- raise ValueError("The row remains partial / is not committed.")
+ self._row_merger.finalize()
break
except InvalidRetryRequest:
self._cancelled = True
break
- for chunk in response.chunks:
+ for row in self._row_merger.process_chunks(response):
+ self.last_scanned_row_key = self._row_merger.last_seen_row_key
+ self._counter += 1
+
+ yield row
+
if self._cancelled:
break
- self._process_chunk(chunk)
- if chunk.commit_row:
- self.last_scanned_row_key = self._previous_row.row_key
- self._counter += 1
- yield self._previous_row
-
- resp_last_key = response.last_scanned_row_key
- if resp_last_key and resp_last_key > self.last_scanned_row_key:
- self.last_scanned_row_key = resp_last_key
-
- def _process_chunk(self, chunk):
- if chunk.reset_row:
- self._validate_chunk_reset_row(chunk)
- self._row = None
- self._cell = self._previous_cell = None
- self._state = self.STATE_NEW_ROW
- return
-
- self._update_cell(chunk)
-
- if self._row is None:
- if (
- self._previous_row is not None
- and self._cell.row_key <= self._previous_row.row_key
- ):
- raise InvalidChunk()
- self._row = PartialRowData(self._cell.row_key)
-
- if chunk.value_size == 0:
- self._state = self.STATE_ROW_IN_PROGRESS
- self._save_current_cell()
- else:
- self._state = self.STATE_CELL_IN_PROGRESS
-
- if chunk.commit_row:
- if chunk.value_size > 0:
- raise InvalidChunk()
-
- self._previous_row = self._row
- self._row = None
- self._previous_cell = None
- self._state = self.STATE_NEW_ROW
-
- def _update_cell(self, chunk):
- if self._cell is None:
- qualifier = None
- if "qualifier" in chunk:
- qualifier = chunk.qualifier
- family = None
- if "family_name" in chunk:
- family = chunk.family_name
-
- self._cell = PartialCellData(
- chunk.row_key,
- family,
- qualifier,
- chunk.timestamp_micros,
- chunk.labels,
- chunk.value,
- )
- self._copy_from_previous(self._cell)
- self._validate_cell_data_new_cell()
- else:
- self._cell.append_value(chunk.value)
-
- def _validate_cell_data_new_cell(self):
- cell = self._cell
- if not cell.row_key or not cell.family_name or cell.qualifier is None:
- raise InvalidChunk()
-
- prev = self._previous_cell
- if prev and prev.row_key != cell.row_key:
- raise InvalidChunk()
-
- def _validate_chunk_reset_row(self, chunk):
- # No reset for new row
- _raise_if(self._state == self.STATE_NEW_ROW)
-
- # No reset with other keys
- _raise_if(chunk.row_key)
- _raise_if("family_name" in chunk)
- _raise_if("qualifier" in chunk)
- _raise_if(chunk.timestamp_micros)
- _raise_if(chunk.labels)
- _raise_if(chunk.value_size)
- _raise_if(chunk.value)
- _raise_if(chunk.commit_row)
-
- def _save_current_cell(self):
- """Helper for :meth:`consume_next`."""
- row, cell = self._row, self._cell
- family = row._cells.setdefault(cell.family_name, {})
- qualified = family.setdefault(cell.qualifier, [])
- complete = Cell.from_pb(cell)
- qualified.append(complete)
- self._cell, self._previous_cell = None, cell
-
- def _copy_from_previous(self, cell):
- """Helper for :meth:`consume_next`."""
- previous = self._previous_cell
- if previous is not None:
- if not cell.row_key:
- cell.row_key = previous.row_key
- if not cell.family_name:
- cell.family_name = previous.family_name
- # NOTE: ``cell.qualifier`` **can** be empty string.
- if cell.qualifier is None:
- cell.qualifier = previous.qualifier
+ # The last response might not have generated any rows, but it
+ # could've updated last_scanned_row_key
+ self.last_scanned_row_key = self._row_merger.last_seen_row_key
class _ReadRowsRequestManager(object):
@@ -714,9 +378,3 @@ def _start_key_set(row_range):
def _end_key_set(row_range):
"""Helper for :meth:`_filter_row_ranges`"""
return row_range.end_key_open or row_range.end_key_closed
-
-
-def _raise_if(predicate, *args):
- """Helper for validation methods."""
- if predicate:
- raise InvalidChunk(*args)
diff --git a/google/cloud/bigtable/row_merger.py b/google/cloud/bigtable/row_merger.py
new file mode 100644
index 000000000..515b91df7
--- /dev/null
+++ b/google/cloud/bigtable/row_merger.py
@@ -0,0 +1,250 @@
+from enum import Enum
+from collections import OrderedDict
+from google.cloud.bigtable.row import Cell, PartialRowData, InvalidChunk
+
+_MISSING_COLUMN_FAMILY = "Column family {} is not among the cells stored in this row."
+_MISSING_COLUMN = (
+ "Column {} is not among the cells stored in this row in the column family {}."
+)
+_MISSING_INDEX = (
+ "Index {!r} is not valid for the cells stored in this row for column {} "
+ "in the column family {}. There are {} such cells."
+)
+
+
+class _State(Enum):
+ ROW_START = "ROW_START"
+ CELL_START = "CELL_START"
+ CELL_IN_PROGRESS = "CELL_IN_PROGRESS"
+ CELL_COMPLETE = "CELL_COMPLETE"
+ ROW_COMPLETE = "ROW_COMPLETE"
+
+
+class _PartialRow(object):
+ __slots__ = [
+ "row_key",
+ "cells",
+ "last_family",
+ "last_family_cells",
+ "last_qualifier",
+ "last_qualifier_cells",
+ "cell",
+ ]
+
+ def __init__(self, row_key):
+ self.row_key = row_key
+ self.cells = OrderedDict()
+
+ self.last_family = None
+ self.last_family_cells = OrderedDict()
+ self.last_qualifier = None
+ self.last_qualifier_cells = []
+
+ self.cell = None
+
+
+class _PartialCell(object):
+ __slots__ = ["family", "qualifier", "timestamp", "labels", "value", "value_index"]
+
+ def __init__(self):
+ self.family = None
+ self.qualifier = None
+ self.timestamp = None
+ self.labels = None
+ self.value = None
+ self.value_index = 0
+
+
+class _RowMerger(object):
+ """
+ State machine to merge chunks from a response stream into logical rows.
+
+ The implementation is a fairly linear state machine that is implemented as
+ a method for every state in the _State enum. In general the states flow
+ from top to bottom with some repetition. Each state handler will do some
+ sanity checks, update in progress data and set the next state.
+
+ There can be multiple state transitions for each chunk, i.e. a single chunk
+ row will flow from ROW_START -> CELL_START -> CELL_COMPLETE -> ROW_COMPLETE
+ in a single iteration.
+ """
+
+ __slots__ = ["state", "last_seen_row_key", "row"]
+
+ def __init__(self, last_seen_row=b""):
+ self.last_seen_row_key = last_seen_row
+ self.state = _State.ROW_START
+ self.row = None
+
+ def process_chunks(self, response):
+ """
+ Process the chunks in the given response and yield logical rows.
+ This class will maintain state across multiple response protos.
+ """
+ if response.last_scanned_row_key:
+ if self.last_seen_row_key >= response.last_scanned_row_key:
+ raise InvalidChunk("Last scanned row key is out of order")
+ self.last_seen_row_key = response.last_scanned_row_key
+
+ for chunk in response.chunks:
+ if chunk.reset_row:
+ self._handle_reset(chunk)
+ continue
+
+ if self.state == _State.ROW_START:
+ self._handle_row_start(chunk)
+
+ if self.state == _State.CELL_START:
+ self._handle_cell_start(chunk)
+
+ if self.state == _State.CELL_IN_PROGRESS:
+ self._handle_cell_in_progress(chunk)
+
+ if self.state == _State.CELL_COMPLETE:
+ self._handle_cell_complete(chunk)
+
+ if self.state == _State.ROW_COMPLETE:
+ yield self._handle_row_complete(chunk)
+ elif chunk.commit_row:
+ raise InvalidChunk(
+ f"Chunk tried to commit row in wrong state (${self.state})"
+ )
+
+ def _handle_reset(self, chunk):
+ if self.state == _State.ROW_START:
+ raise InvalidChunk("Bare reset")
+ if chunk.row_key:
+ raise InvalidChunk("Reset chunk has a row key")
+ if chunk.HasField("family_name"):
+ raise InvalidChunk("Reset chunk has family_name")
+ if chunk.HasField("qualifier"):
+ raise InvalidChunk("Reset chunk has qualifier")
+ if chunk.timestamp_micros:
+ raise InvalidChunk("Reset chunk has a timestamp")
+ if chunk.labels:
+ raise InvalidChunk("Reset chunk has labels")
+ if chunk.value:
+ raise InvalidChunk("Reset chunk has a value")
+
+ self.state = _State.ROW_START
+ self.row = None
+
+ def _handle_row_start(self, chunk):
+ if not chunk.row_key:
+ raise InvalidChunk("New row is missing a row key")
+ if self.last_seen_row_key and self.last_seen_row_key >= chunk.row_key:
+ raise InvalidChunk("Out of order row keys")
+
+ self.row = _PartialRow(chunk.row_key)
+ self.state = _State.CELL_START
+
+ def _handle_cell_start(self, chunk):
+ # Ensure that all chunks after the first one either are missing a row
+ # key or the row is the same
+ if self.row.cells and chunk.row_key and chunk.row_key != self.row.row_key:
+ raise InvalidChunk("row key changed mid row")
+
+ if not self.row.cell:
+ self.row.cell = _PartialCell()
+
+ # Cells can inherit family/qualifier from previous cells
+ # However if the family changes, then qualifier must be specified as well
+ if chunk.HasField("family_name"):
+ self.row.cell.family = chunk.family_name.value
+ self.row.cell.qualifier = None
+ if not self.row.cell.family:
+ raise InvalidChunk("missing family for a new cell")
+
+ if chunk.HasField("qualifier"):
+ self.row.cell.qualifier = chunk.qualifier.value
+ if self.row.cell.qualifier is None:
+ raise InvalidChunk("missing qualifier for a new cell")
+
+ self.row.cell.timestamp = chunk.timestamp_micros
+ self.row.cell.labels = chunk.labels
+
+ if chunk.value_size > 0:
+ # explicitly avoid pre-allocation as it seems that bytearray
+ # concatenation performs better than slice copies.
+ self.row.cell.value = bytearray()
+ self.state = _State.CELL_IN_PROGRESS
+ else:
+ self.row.cell.value = chunk.value
+ self.state = _State.CELL_COMPLETE
+
+ def _handle_cell_in_progress(self, chunk):
+ # if this isn't the first cell chunk, make sure that everything except
+ # the value stayed constant.
+ if self.row.cell.value_index > 0:
+ if chunk.row_key:
+ raise InvalidChunk("found row key mid cell")
+ if chunk.HasField("family_name"):
+ raise InvalidChunk("In progress cell had a family name")
+ if chunk.HasField("qualifier"):
+ raise InvalidChunk("In progress cell had a qualifier")
+ if chunk.timestamp_micros:
+ raise InvalidChunk("In progress cell had a timestamp")
+ if chunk.labels:
+ raise InvalidChunk("In progress cell had labels")
+
+ self.row.cell.value += chunk.value
+ self.row.cell.value_index += len(chunk.value)
+
+ if chunk.value_size > 0:
+ self.state = _State.CELL_IN_PROGRESS
+ else:
+ self.row.cell.value = bytes(self.row.cell.value)
+ self.state = _State.CELL_COMPLETE
+
+ def _handle_cell_complete(self, chunk):
+ # since we are guaranteed that all family & qualifier cells are
+ # contiguous, we can optimize away the dict lookup by caching the last
+ # family/qualifier and simply comparing and appending
+ family_changed = False
+ if self.row.last_family != self.row.cell.family:
+ family_changed = True
+ self.row.last_family = self.row.cell.family
+ self.row.cells[
+ self.row.cell.family
+ ] = self.row.last_family_cells = OrderedDict()
+
+ if family_changed or self.row.last_qualifier != self.row.cell.qualifier:
+ self.row.last_qualifier = self.row.cell.qualifier
+ self.row.last_family_cells[
+ self.row.cell.qualifier
+ ] = self.row.last_qualifier_cells = []
+
+ self.row.last_qualifier_cells.append(
+ Cell(
+ self.row.cell.value,
+ self.row.cell.timestamp,
+ self.row.cell.labels,
+ )
+ )
+
+ self.row.cell.timestamp = 0
+ self.row.cell.value = None
+ self.row.cell.value_index = 0
+
+ if not chunk.commit_row:
+ self.state = _State.CELL_START
+ else:
+ self.state = _State.ROW_COMPLETE
+
+ def _handle_row_complete(self, chunk):
+ new_row = PartialRowData(self.row.row_key)
+ new_row._cells = self.row.cells
+
+ self.last_seen_row_key = new_row.row_key
+ self.row = None
+ self.state = _State.ROW_START
+
+ return new_row
+
+ def finalize(self):
+ """
+ Must be called at the end of the stream to ensure there are no unmerged
+ rows.
+ """
+ if self.row or self.state != _State.ROW_START:
+ raise ValueError("The row remains partial / is not committed.")
diff --git a/google/cloud/bigtable/row_set.py b/google/cloud/bigtable/row_set.py
index 82a540b5a..2bc436d54 100644
--- a/google/cloud/bigtable/row_set.py
+++ b/google/cloud/bigtable/row_set.py
@@ -22,7 +22,7 @@ class RowSet(object):
"""Convenience wrapper of google.bigtable.v2.RowSet
Useful for creating a set of row keys and row ranges, which can
- be passed to yield_rows method of class:`.Table.yield_rows`.
+ be passed to read_rows method of class:`.Table.read_rows`.
"""
def __init__(self):
diff --git a/google/cloud/bigtable/table.py b/google/cloud/bigtable/table.py
index fddd04809..0009f287e 100644
--- a/google/cloud/bigtable/table.py
+++ b/google/cloud/bigtable/table.py
@@ -23,6 +23,7 @@
from google.api_core.exceptions import NotFound
from google.api_core.exceptions import RetryError
from google.api_core.exceptions import ServiceUnavailable
+from google.api_core.exceptions import InternalServerError
from google.api_core.gapic_v1.method import DEFAULT
from google.api_core.retry import if_exception_type
from google.api_core.retry import Retry
@@ -31,19 +32,22 @@
from google.cloud.bigtable.column_family import _gc_rule_from_pb
from google.cloud.bigtable.column_family import ColumnFamily
from google.cloud.bigtable.batcher import MutationsBatcher
-from google.cloud.bigtable.batcher import FLUSH_COUNT, MAX_ROW_BYTES
+from google.cloud.bigtable.batcher import FLUSH_COUNT, MAX_MUTATION_SIZE
from google.cloud.bigtable.encryption_info import EncryptionInfo
from google.cloud.bigtable.policy import Policy
from google.cloud.bigtable.row import AppendRow
from google.cloud.bigtable.row import ConditionalRow
from google.cloud.bigtable.row import DirectRow
-from google.cloud.bigtable.row_data import PartialRowsData
+from google.cloud.bigtable.row_data import (
+ PartialRowsData,
+ _retriable_internal_server_error,
+)
from google.cloud.bigtable.row_data import DEFAULT_RETRY_READ_ROWS
from google.cloud.bigtable.row_set import RowSet
from google.cloud.bigtable.row_set import RowRange
from google.cloud.bigtable import enums
from google.cloud.bigtable_v2.types import bigtable as data_messages_v2_pb2
-from google.cloud.bigtable_admin_v2 import BigtableTableAdminClient
+from google.cloud.bigtable_admin_v2 import BaseBigtableTableAdminClient
from google.cloud.bigtable_admin_v2.types import table as admin_messages_v2_pb2
from google.cloud.bigtable_admin_v2.types import (
bigtable_table_admin as table_admin_messages_v2_pb2,
@@ -55,9 +59,15 @@
_MAX_BULK_MUTATIONS = 100000
VIEW_NAME_ONLY = enums.Table.View.NAME_ONLY
-RETRYABLE_MUTATION_ERRORS = (Aborted, DeadlineExceeded, ServiceUnavailable)
+RETRYABLE_MUTATION_ERRORS = (
+ Aborted,
+ DeadlineExceeded,
+ ServiceUnavailable,
+ InternalServerError,
+)
"""Errors which can be retried during row mutation."""
+
RETRYABLE_CODES: Set[int] = set()
for retryable in RETRYABLE_MUTATION_ERRORS:
@@ -523,7 +533,7 @@ def get_encryption_info(self):
for cluster_id, value_pb in table_pb.cluster_states.items()
}
- def read_row(self, row_key, filter_=None):
+ def read_row(self, row_key, filter_=None, retry=DEFAULT_RETRY_READ_ROWS):
"""Read a single row from this table.
For example:
@@ -540,6 +550,14 @@ def read_row(self, row_key, filter_=None):
:param filter_: (Optional) The filter to apply to the contents of the
row. If unset, returns the entire row.
+ :type retry: :class:`~google.api_core.retry.Retry`
+ :param retry:
+ (Optional) Retry delay and deadline arguments. To override, the
+ default value :attr:`DEFAULT_RETRY_READ_ROWS` can be used and
+ modified with the :meth:`~google.api_core.retry.Retry.with_delay`
+ method or the :meth:`~google.api_core.retry.Retry.with_deadline`
+ method.
+
:rtype: :class:`.PartialRowData`, :data:`NoneType `
:returns: The contents of the row if any chunks were returned in
the response, otherwise :data:`None`.
@@ -548,7 +566,9 @@ def read_row(self, row_key, filter_=None):
"""
row_set = RowSet()
row_set.add_row_key(row_key)
- result_iter = iter(self.read_rows(filter_=filter_, row_set=row_set))
+ result_iter = iter(
+ self.read_rows(filter_=filter_, row_set=row_set, retry=retry)
+ )
row = next(result_iter, None)
if next(result_iter, None) is not None:
raise ValueError("More than one row was returned.")
@@ -834,7 +854,9 @@ def drop_by_prefix(self, row_key_prefix, timeout=None):
request={"name": self.name, "row_key_prefix": _to_bytes(row_key_prefix)}
)
- def mutations_batcher(self, flush_count=FLUSH_COUNT, max_row_bytes=MAX_ROW_BYTES):
+ def mutations_batcher(
+ self, flush_count=FLUSH_COUNT, max_row_bytes=MAX_MUTATION_SIZE
+ ):
"""Factory to create a mutation batcher associated with this instance.
For example:
@@ -968,7 +990,7 @@ def list_backups(self, cluster_id=None, filter_=None, order_by=None, page_size=0
if filter_:
backups_filter = "({}) AND ({})".format(backups_filter, filter_)
- parent = BigtableTableAdminClient.cluster_path(
+ parent = BaseBigtableTableAdminClient.cluster_path(
project=self._instance._client.project,
instance=self._instance.instance_id,
cluster=cluster_id,
@@ -1015,7 +1037,7 @@ def restore(self, new_table_id, cluster_id=None, backup_id=None, backup_name=Non
and `backup_id` parameters even of such specified.
:return: An instance of
- :class:`~google.cloud.bigtable_admin_v2.types._OperationFuture`.
+ :class:`~google.api_core.operation.Operation`.
:raises: google.api_core.exceptions.AlreadyExists: If the table
already exists.
@@ -1027,13 +1049,13 @@ def restore(self, new_table_id, cluster_id=None, backup_id=None, backup_name=Non
"""
api = self._instance._client.table_admin_client
if not backup_name:
- backup_name = BigtableTableAdminClient.backup_path(
+ backup_name = BaseBigtableTableAdminClient.backup_path(
project=self._instance._client.project,
instance=self._instance.instance_id,
cluster=cluster_id,
backup=backup_id,
)
- return api.restore_table(
+ return api._restore_table(
request={
"parent": self._instance.name,
"table_id": new_table_id,
@@ -1130,11 +1152,18 @@ def _do_mutate_retryable_rows(self):
retry=None,
**kwargs
)
- except RETRYABLE_MUTATION_ERRORS:
+ except RETRYABLE_MUTATION_ERRORS as exc:
# If an exception, considered retryable by `RETRYABLE_MUTATION_ERRORS`, is
# returned from the initial call, consider
# it to be retryable. Wrap as a Bigtable Retryable Error.
- raise _BigtableRetryableError
+ # For InternalServerError, it is only retriable if the message is related to RST Stream messages
+ if _retriable_internal_server_error(exc) or not isinstance(
+ exc, InternalServerError
+ ):
+ raise _BigtableRetryableError
+ else:
+ # re-raise the original exception
+ raise
num_responses = 0
num_retryable_responses = 0
diff --git a/google/cloud/bigtable_admin/__init__.py b/google/cloud/bigtable_admin/__init__.py
new file mode 100644
index 000000000..2d95b06c8
--- /dev/null
+++ b/google/cloud/bigtable_admin/__init__.py
@@ -0,0 +1,455 @@
+# -*- coding: utf-8 -*-
+# Copyright 2025 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.
+#
+from google.cloud.bigtable_admin import gapic_version as package_version
+
+__version__ = package_version.__version__
+
+
+from google.cloud.bigtable_admin_v2.services.bigtable_instance_admin.client import (
+ BigtableInstanceAdminClient,
+)
+from google.cloud.bigtable_admin_v2.services.bigtable_instance_admin.async_client import (
+ BigtableInstanceAdminAsyncClient,
+)
+from google.cloud.bigtable_admin_v2.services.bigtable_table_admin.client import (
+ BaseBigtableTableAdminClient,
+)
+from google.cloud.bigtable_admin_v2.services.bigtable_table_admin.async_client import (
+ BaseBigtableTableAdminAsyncClient,
+)
+
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ CreateAppProfileRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ CreateClusterMetadata,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ CreateClusterRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ CreateInstanceMetadata,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ CreateInstanceRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ CreateLogicalViewMetadata,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ CreateLogicalViewRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ CreateMaterializedViewMetadata,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ CreateMaterializedViewRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ DeleteAppProfileRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ DeleteClusterRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ DeleteInstanceRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ DeleteLogicalViewRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ DeleteMaterializedViewRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ GetAppProfileRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ GetClusterRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ GetInstanceRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ GetLogicalViewRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ GetMaterializedViewRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ ListAppProfilesRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ ListAppProfilesResponse,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ ListClustersRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ ListClustersResponse,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ ListHotTabletsRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ ListHotTabletsResponse,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ ListInstancesRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ ListInstancesResponse,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ ListLogicalViewsRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ ListLogicalViewsResponse,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ ListMaterializedViewsRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ ListMaterializedViewsResponse,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ PartialUpdateClusterMetadata,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ PartialUpdateClusterRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ PartialUpdateInstanceRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ UpdateAppProfileMetadata,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ UpdateAppProfileRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ UpdateClusterMetadata,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ UpdateInstanceMetadata,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ UpdateLogicalViewMetadata,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ UpdateLogicalViewRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ UpdateMaterializedViewMetadata,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_instance_admin import (
+ UpdateMaterializedViewRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ CheckConsistencyRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ CheckConsistencyResponse,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import CopyBackupMetadata
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import CopyBackupRequest
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ CreateAuthorizedViewMetadata,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ CreateAuthorizedViewRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ CreateBackupMetadata,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ CreateBackupRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ CreateSchemaBundleMetadata,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ CreateSchemaBundleRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ CreateTableFromSnapshotMetadata,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ CreateTableFromSnapshotRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import CreateTableRequest
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ DataBoostReadLocalWrites,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ DeleteAuthorizedViewRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ DeleteBackupRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ DeleteSchemaBundleRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ DeleteSnapshotRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import DeleteTableRequest
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ DropRowRangeRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ GenerateConsistencyTokenRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ GenerateConsistencyTokenResponse,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ GetAuthorizedViewRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import GetBackupRequest
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ GetSchemaBundleRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import GetSnapshotRequest
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import GetTableRequest
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ ListAuthorizedViewsRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ ListAuthorizedViewsResponse,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import ListBackupsRequest
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ ListBackupsResponse,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ ListSchemaBundlesRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ ListSchemaBundlesResponse,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ ListSnapshotsRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ ListSnapshotsResponse,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import ListTablesRequest
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import ListTablesResponse
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ ModifyColumnFamiliesRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ OptimizeRestoredTableMetadata,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ RestoreTableMetadata,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ RestoreTableRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ SnapshotTableMetadata,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ SnapshotTableRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ StandardReadRemoteWrites,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ UndeleteTableMetadata,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ UndeleteTableRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ UpdateAuthorizedViewMetadata,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ UpdateAuthorizedViewRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ UpdateBackupRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ UpdateSchemaBundleMetadata,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ UpdateSchemaBundleRequest,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import (
+ UpdateTableMetadata,
+)
+from google.cloud.bigtable_admin_v2.types.bigtable_table_admin import UpdateTableRequest
+from google.cloud.bigtable_admin_v2.types.common import OperationProgress
+from google.cloud.bigtable_admin_v2.types.common import StorageType
+from google.cloud.bigtable_admin_v2.types.instance import AppProfile
+from google.cloud.bigtable_admin_v2.types.instance import AutoscalingLimits
+from google.cloud.bigtable_admin_v2.types.instance import AutoscalingTargets
+from google.cloud.bigtable_admin_v2.types.instance import Cluster
+from google.cloud.bigtable_admin_v2.types.instance import HotTablet
+from google.cloud.bigtable_admin_v2.types.instance import Instance
+from google.cloud.bigtable_admin_v2.types.instance import LogicalView
+from google.cloud.bigtable_admin_v2.types.instance import MaterializedView
+from google.cloud.bigtable_admin_v2.types.table import AuthorizedView
+from google.cloud.bigtable_admin_v2.types.table import Backup
+from google.cloud.bigtable_admin_v2.types.table import BackupInfo
+from google.cloud.bigtable_admin_v2.types.table import ChangeStreamConfig
+from google.cloud.bigtable_admin_v2.types.table import ColumnFamily
+from google.cloud.bigtable_admin_v2.types.table import EncryptionInfo
+from google.cloud.bigtable_admin_v2.types.table import GcRule
+from google.cloud.bigtable_admin_v2.types.table import ProtoSchema
+from google.cloud.bigtable_admin_v2.types.table import RestoreInfo
+from google.cloud.bigtable_admin_v2.types.table import SchemaBundle
+from google.cloud.bigtable_admin_v2.types.table import Snapshot
+from google.cloud.bigtable_admin_v2.types.table import Table
+from google.cloud.bigtable_admin_v2.types.table import TieredStorageConfig
+from google.cloud.bigtable_admin_v2.types.table import TieredStorageRule
+from google.cloud.bigtable_admin_v2.types.table import RestoreSourceType
+from google.cloud.bigtable_admin_v2.types.types import Type
+
+__all__ = (
+ "BigtableInstanceAdminClient",
+ "BigtableInstanceAdminAsyncClient",
+ "BaseBigtableTableAdminClient",
+ "BaseBigtableTableAdminAsyncClient",
+ "CreateAppProfileRequest",
+ "CreateClusterMetadata",
+ "CreateClusterRequest",
+ "CreateInstanceMetadata",
+ "CreateInstanceRequest",
+ "CreateLogicalViewMetadata",
+ "CreateLogicalViewRequest",
+ "CreateMaterializedViewMetadata",
+ "CreateMaterializedViewRequest",
+ "DeleteAppProfileRequest",
+ "DeleteClusterRequest",
+ "DeleteInstanceRequest",
+ "DeleteLogicalViewRequest",
+ "DeleteMaterializedViewRequest",
+ "GetAppProfileRequest",
+ "GetClusterRequest",
+ "GetInstanceRequest",
+ "GetLogicalViewRequest",
+ "GetMaterializedViewRequest",
+ "ListAppProfilesRequest",
+ "ListAppProfilesResponse",
+ "ListClustersRequest",
+ "ListClustersResponse",
+ "ListHotTabletsRequest",
+ "ListHotTabletsResponse",
+ "ListInstancesRequest",
+ "ListInstancesResponse",
+ "ListLogicalViewsRequest",
+ "ListLogicalViewsResponse",
+ "ListMaterializedViewsRequest",
+ "ListMaterializedViewsResponse",
+ "PartialUpdateClusterMetadata",
+ "PartialUpdateClusterRequest",
+ "PartialUpdateInstanceRequest",
+ "UpdateAppProfileMetadata",
+ "UpdateAppProfileRequest",
+ "UpdateClusterMetadata",
+ "UpdateInstanceMetadata",
+ "UpdateLogicalViewMetadata",
+ "UpdateLogicalViewRequest",
+ "UpdateMaterializedViewMetadata",
+ "UpdateMaterializedViewRequest",
+ "CheckConsistencyRequest",
+ "CheckConsistencyResponse",
+ "CopyBackupMetadata",
+ "CopyBackupRequest",
+ "CreateAuthorizedViewMetadata",
+ "CreateAuthorizedViewRequest",
+ "CreateBackupMetadata",
+ "CreateBackupRequest",
+ "CreateSchemaBundleMetadata",
+ "CreateSchemaBundleRequest",
+ "CreateTableFromSnapshotMetadata",
+ "CreateTableFromSnapshotRequest",
+ "CreateTableRequest",
+ "DataBoostReadLocalWrites",
+ "DeleteAuthorizedViewRequest",
+ "DeleteBackupRequest",
+ "DeleteSchemaBundleRequest",
+ "DeleteSnapshotRequest",
+ "DeleteTableRequest",
+ "DropRowRangeRequest",
+ "GenerateConsistencyTokenRequest",
+ "GenerateConsistencyTokenResponse",
+ "GetAuthorizedViewRequest",
+ "GetBackupRequest",
+ "GetSchemaBundleRequest",
+ "GetSnapshotRequest",
+ "GetTableRequest",
+ "ListAuthorizedViewsRequest",
+ "ListAuthorizedViewsResponse",
+ "ListBackupsRequest",
+ "ListBackupsResponse",
+ "ListSchemaBundlesRequest",
+ "ListSchemaBundlesResponse",
+ "ListSnapshotsRequest",
+ "ListSnapshotsResponse",
+ "ListTablesRequest",
+ "ListTablesResponse",
+ "ModifyColumnFamiliesRequest",
+ "OptimizeRestoredTableMetadata",
+ "RestoreTableMetadata",
+ "RestoreTableRequest",
+ "SnapshotTableMetadata",
+ "SnapshotTableRequest",
+ "StandardReadRemoteWrites",
+ "UndeleteTableMetadata",
+ "UndeleteTableRequest",
+ "UpdateAuthorizedViewMetadata",
+ "UpdateAuthorizedViewRequest",
+ "UpdateBackupRequest",
+ "UpdateSchemaBundleMetadata",
+ "UpdateSchemaBundleRequest",
+ "UpdateTableMetadata",
+ "UpdateTableRequest",
+ "OperationProgress",
+ "StorageType",
+ "AppProfile",
+ "AutoscalingLimits",
+ "AutoscalingTargets",
+ "Cluster",
+ "HotTablet",
+ "Instance",
+ "LogicalView",
+ "MaterializedView",
+ "AuthorizedView",
+ "Backup",
+ "BackupInfo",
+ "ChangeStreamConfig",
+ "ColumnFamily",
+ "EncryptionInfo",
+ "GcRule",
+ "ProtoSchema",
+ "RestoreInfo",
+ "SchemaBundle",
+ "Snapshot",
+ "Table",
+ "TieredStorageConfig",
+ "TieredStorageRule",
+ "RestoreSourceType",
+ "Type",
+)
+
+import google.cloud.bigtable_admin_v2.overlay # noqa: F401
+from google.cloud.bigtable_admin_v2.overlay import * # noqa: F401, F403
+
+__all__ += google.cloud.bigtable_admin_v2.overlay.__all__
diff --git a/google/cloud/bigtable_admin/gapic_version.py b/google/cloud/bigtable_admin/gapic_version.py
new file mode 100644
index 000000000..6d72a226d
--- /dev/null
+++ b/google/cloud/bigtable_admin/gapic_version.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+# Copyright 2025 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.
+#
+__version__ = "2.35.0" # {x-release-please-version}
diff --git a/google/cloud/bigtable_admin/py.typed b/google/cloud/bigtable_admin/py.typed
new file mode 100644
index 000000000..bc26f2069
--- /dev/null
+++ b/google/cloud/bigtable_admin/py.typed
@@ -0,0 +1,2 @@
+# Marker file for PEP 561.
+# The google-cloud-bigtable-admin package uses inline types.
diff --git a/google/cloud/bigtable_admin_v2/__init__.py b/google/cloud/bigtable_admin_v2/__init__.py
index 3713dc1e8..6a47979fd 100644
--- a/google/cloud/bigtable_admin_v2/__init__.py
+++ b/google/cloud/bigtable_admin_v2/__init__.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -13,23 +13,45 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+from google.cloud.bigtable_admin_v2 import gapic_version as package_version
+
+import google.api_core as api_core
+import sys
+
+__version__ = package_version.__version__
+
+if sys.version_info >= (3, 8): # pragma: NO COVER
+ from importlib import metadata
+else: # pragma: NO COVER
+ # TODO(https://github.com/googleapis/python-api-core/issues/835): Remove
+ # this code path once we drop support for Python 3.7
+ import importlib_metadata as metadata
+
from .services.bigtable_instance_admin import BigtableInstanceAdminClient
from .services.bigtable_instance_admin import BigtableInstanceAdminAsyncClient
-from .services.bigtable_table_admin import BigtableTableAdminClient
-from .services.bigtable_table_admin import BigtableTableAdminAsyncClient
+from .services.bigtable_table_admin import BaseBigtableTableAdminClient
+from .services.bigtable_table_admin import BaseBigtableTableAdminAsyncClient
from .types.bigtable_instance_admin import CreateAppProfileRequest
from .types.bigtable_instance_admin import CreateClusterMetadata
from .types.bigtable_instance_admin import CreateClusterRequest
from .types.bigtable_instance_admin import CreateInstanceMetadata
from .types.bigtable_instance_admin import CreateInstanceRequest
+from .types.bigtable_instance_admin import CreateLogicalViewMetadata
+from .types.bigtable_instance_admin import CreateLogicalViewRequest
+from .types.bigtable_instance_admin import CreateMaterializedViewMetadata
+from .types.bigtable_instance_admin import CreateMaterializedViewRequest
from .types.bigtable_instance_admin import DeleteAppProfileRequest
from .types.bigtable_instance_admin import DeleteClusterRequest
from .types.bigtable_instance_admin import DeleteInstanceRequest
+from .types.bigtable_instance_admin import DeleteLogicalViewRequest
+from .types.bigtable_instance_admin import DeleteMaterializedViewRequest
from .types.bigtable_instance_admin import GetAppProfileRequest
from .types.bigtable_instance_admin import GetClusterRequest
from .types.bigtable_instance_admin import GetInstanceRequest
+from .types.bigtable_instance_admin import GetLogicalViewRequest
+from .types.bigtable_instance_admin import GetMaterializedViewRequest
from .types.bigtable_instance_admin import ListAppProfilesRequest
from .types.bigtable_instance_admin import ListAppProfilesResponse
from .types.bigtable_instance_admin import ListClustersRequest
@@ -38,6 +60,10 @@
from .types.bigtable_instance_admin import ListHotTabletsResponse
from .types.bigtable_instance_admin import ListInstancesRequest
from .types.bigtable_instance_admin import ListInstancesResponse
+from .types.bigtable_instance_admin import ListLogicalViewsRequest
+from .types.bigtable_instance_admin import ListLogicalViewsResponse
+from .types.bigtable_instance_admin import ListMaterializedViewsRequest
+from .types.bigtable_instance_admin import ListMaterializedViewsResponse
from .types.bigtable_instance_admin import PartialUpdateClusterMetadata
from .types.bigtable_instance_admin import PartialUpdateClusterRequest
from .types.bigtable_instance_admin import PartialUpdateInstanceRequest
@@ -45,24 +71,43 @@
from .types.bigtable_instance_admin import UpdateAppProfileRequest
from .types.bigtable_instance_admin import UpdateClusterMetadata
from .types.bigtable_instance_admin import UpdateInstanceMetadata
+from .types.bigtable_instance_admin import UpdateLogicalViewMetadata
+from .types.bigtable_instance_admin import UpdateLogicalViewRequest
+from .types.bigtable_instance_admin import UpdateMaterializedViewMetadata
+from .types.bigtable_instance_admin import UpdateMaterializedViewRequest
from .types.bigtable_table_admin import CheckConsistencyRequest
from .types.bigtable_table_admin import CheckConsistencyResponse
+from .types.bigtable_table_admin import CopyBackupMetadata
+from .types.bigtable_table_admin import CopyBackupRequest
+from .types.bigtable_table_admin import CreateAuthorizedViewMetadata
+from .types.bigtable_table_admin import CreateAuthorizedViewRequest
from .types.bigtable_table_admin import CreateBackupMetadata
from .types.bigtable_table_admin import CreateBackupRequest
+from .types.bigtable_table_admin import CreateSchemaBundleMetadata
+from .types.bigtable_table_admin import CreateSchemaBundleRequest
from .types.bigtable_table_admin import CreateTableFromSnapshotMetadata
from .types.bigtable_table_admin import CreateTableFromSnapshotRequest
from .types.bigtable_table_admin import CreateTableRequest
+from .types.bigtable_table_admin import DataBoostReadLocalWrites
+from .types.bigtable_table_admin import DeleteAuthorizedViewRequest
from .types.bigtable_table_admin import DeleteBackupRequest
+from .types.bigtable_table_admin import DeleteSchemaBundleRequest
from .types.bigtable_table_admin import DeleteSnapshotRequest
from .types.bigtable_table_admin import DeleteTableRequest
from .types.bigtable_table_admin import DropRowRangeRequest
from .types.bigtable_table_admin import GenerateConsistencyTokenRequest
from .types.bigtable_table_admin import GenerateConsistencyTokenResponse
+from .types.bigtable_table_admin import GetAuthorizedViewRequest
from .types.bigtable_table_admin import GetBackupRequest
+from .types.bigtable_table_admin import GetSchemaBundleRequest
from .types.bigtable_table_admin import GetSnapshotRequest
from .types.bigtable_table_admin import GetTableRequest
+from .types.bigtable_table_admin import ListAuthorizedViewsRequest
+from .types.bigtable_table_admin import ListAuthorizedViewsResponse
from .types.bigtable_table_admin import ListBackupsRequest
from .types.bigtable_table_admin import ListBackupsResponse
+from .types.bigtable_table_admin import ListSchemaBundlesRequest
+from .types.bigtable_table_admin import ListSchemaBundlesResponse
from .types.bigtable_table_admin import ListSnapshotsRequest
from .types.bigtable_table_admin import ListSnapshotsResponse
from .types.bigtable_table_admin import ListTablesRequest
@@ -73,7 +118,16 @@
from .types.bigtable_table_admin import RestoreTableRequest
from .types.bigtable_table_admin import SnapshotTableMetadata
from .types.bigtable_table_admin import SnapshotTableRequest
+from .types.bigtable_table_admin import StandardReadRemoteWrites
+from .types.bigtable_table_admin import UndeleteTableMetadata
+from .types.bigtable_table_admin import UndeleteTableRequest
+from .types.bigtable_table_admin import UpdateAuthorizedViewMetadata
+from .types.bigtable_table_admin import UpdateAuthorizedViewRequest
from .types.bigtable_table_admin import UpdateBackupRequest
+from .types.bigtable_table_admin import UpdateSchemaBundleMetadata
+from .types.bigtable_table_admin import UpdateSchemaBundleRequest
+from .types.bigtable_table_admin import UpdateTableMetadata
+from .types.bigtable_table_admin import UpdateTableRequest
from .types.common import OperationProgress
from .types.common import StorageType
from .types.instance import AppProfile
@@ -82,44 +136,164 @@
from .types.instance import Cluster
from .types.instance import HotTablet
from .types.instance import Instance
+from .types.instance import LogicalView
+from .types.instance import MaterializedView
+from .types.table import AuthorizedView
from .types.table import Backup
from .types.table import BackupInfo
+from .types.table import ChangeStreamConfig
from .types.table import ColumnFamily
from .types.table import EncryptionInfo
from .types.table import GcRule
+from .types.table import ProtoSchema
from .types.table import RestoreInfo
+from .types.table import SchemaBundle
from .types.table import Snapshot
from .types.table import Table
+from .types.table import TieredStorageConfig
+from .types.table import TieredStorageRule
from .types.table import RestoreSourceType
+from .types.types import Type
+
+if hasattr(api_core, "check_python_version") and hasattr(
+ api_core, "check_dependency_versions"
+): # pragma: NO COVER
+ api_core.check_python_version("google.cloud.bigtable_admin_v2") # type: ignore
+ api_core.check_dependency_versions("google.cloud.bigtable_admin_v2") # type: ignore
+else: # pragma: NO COVER
+ # An older version of api_core is installed which does not define the
+ # functions above. We do equivalent checks manually.
+ try:
+ import warnings
+ import sys
+
+ _py_version_str = sys.version.split()[0]
+ _package_label = "google.cloud.bigtable_admin_v2"
+ if sys.version_info < (3, 9):
+ warnings.warn(
+ "You are using a non-supported Python version "
+ + f"({_py_version_str}). Google will not post any further "
+ + f"updates to {_package_label} supporting this Python version. "
+ + "Please upgrade to the latest Python version, or at "
+ + f"least to Python 3.9, and then update {_package_label}.",
+ FutureWarning,
+ )
+ if sys.version_info[:2] == (3, 9):
+ warnings.warn(
+ f"You are using a Python version ({_py_version_str}) "
+ + f"which Google will stop supporting in {_package_label} in "
+ + "January 2026. Please "
+ + "upgrade to the latest Python version, or at "
+ + "least to Python 3.10, before then, and "
+ + f"then update {_package_label}.",
+ FutureWarning,
+ )
+
+ def parse_version_to_tuple(version_string: str):
+ """Safely converts a semantic version string to a comparable tuple of integers.
+ Example: "4.25.8" -> (4, 25, 8)
+ Ignores non-numeric parts and handles common version formats.
+ Args:
+ version_string: Version string in the format "x.y.z" or "x.y.z"
+ Returns:
+ Tuple of integers for the parsed version string.
+ """
+ parts = []
+ for part in version_string.split("."):
+ try:
+ parts.append(int(part))
+ except ValueError:
+ # If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here.
+ # This is a simplification compared to 'packaging.parse_version', but sufficient
+ # for comparing strictly numeric semantic versions.
+ break
+ return tuple(parts)
+
+ def _get_version(dependency_name):
+ try:
+ version_string: str = metadata.version(dependency_name)
+ parsed_version = parse_version_to_tuple(version_string)
+ return (parsed_version, version_string)
+ except Exception:
+ # Catch exceptions from metadata.version() (e.g., PackageNotFoundError)
+ # or errors during parse_version_to_tuple
+ return (None, "--")
+
+ _dependency_package = "google.protobuf"
+ _next_supported_version = "4.25.8"
+ _next_supported_version_tuple = (4, 25, 8)
+ _recommendation = " (we recommend 6.x)"
+ (_version_used, _version_used_string) = _get_version(_dependency_package)
+ if _version_used and _version_used < _next_supported_version_tuple:
+ warnings.warn(
+ f"Package {_package_label} depends on "
+ + f"{_dependency_package}, currently installed at version "
+ + f"{_version_used_string}. Future updates to "
+ + f"{_package_label} will require {_dependency_package} at "
+ + f"version {_next_supported_version} or higher{_recommendation}."
+ + " Please ensure "
+ + "that either (a) your Python environment doesn't pin the "
+ + f"version of {_dependency_package}, so that updates to "
+ + f"{_package_label} can require the higher version, or "
+ + "(b) you manually update your Python environment to use at "
+ + f"least version {_next_supported_version} of "
+ + f"{_dependency_package}.",
+ FutureWarning,
+ )
+ except Exception:
+ warnings.warn(
+ "Could not determine the version of Python "
+ + "currently being used. To continue receiving "
+ + "updates for {_package_label}, ensure you are "
+ + "using a supported version of Python; see "
+ + "https://devguide.python.org/versions/"
+ )
__all__ = (
+ "BaseBigtableTableAdminAsyncClient",
"BigtableInstanceAdminAsyncClient",
- "BigtableTableAdminAsyncClient",
"AppProfile",
+ "AuthorizedView",
"AutoscalingLimits",
"AutoscalingTargets",
"Backup",
"BackupInfo",
+ "BaseBigtableTableAdminClient",
"BigtableInstanceAdminClient",
- "BigtableTableAdminClient",
+ "ChangeStreamConfig",
"CheckConsistencyRequest",
"CheckConsistencyResponse",
"Cluster",
"ColumnFamily",
+ "CopyBackupMetadata",
+ "CopyBackupRequest",
"CreateAppProfileRequest",
+ "CreateAuthorizedViewMetadata",
+ "CreateAuthorizedViewRequest",
"CreateBackupMetadata",
"CreateBackupRequest",
"CreateClusterMetadata",
"CreateClusterRequest",
"CreateInstanceMetadata",
"CreateInstanceRequest",
+ "CreateLogicalViewMetadata",
+ "CreateLogicalViewRequest",
+ "CreateMaterializedViewMetadata",
+ "CreateMaterializedViewRequest",
+ "CreateSchemaBundleMetadata",
+ "CreateSchemaBundleRequest",
"CreateTableFromSnapshotMetadata",
"CreateTableFromSnapshotRequest",
"CreateTableRequest",
+ "DataBoostReadLocalWrites",
"DeleteAppProfileRequest",
+ "DeleteAuthorizedViewRequest",
"DeleteBackupRequest",
"DeleteClusterRequest",
"DeleteInstanceRequest",
+ "DeleteLogicalViewRequest",
+ "DeleteMaterializedViewRequest",
+ "DeleteSchemaBundleRequest",
"DeleteSnapshotRequest",
"DeleteTableRequest",
"DropRowRangeRequest",
@@ -128,15 +302,21 @@
"GenerateConsistencyTokenRequest",
"GenerateConsistencyTokenResponse",
"GetAppProfileRequest",
+ "GetAuthorizedViewRequest",
"GetBackupRequest",
"GetClusterRequest",
"GetInstanceRequest",
+ "GetLogicalViewRequest",
+ "GetMaterializedViewRequest",
+ "GetSchemaBundleRequest",
"GetSnapshotRequest",
"GetTableRequest",
"HotTablet",
"Instance",
"ListAppProfilesRequest",
"ListAppProfilesResponse",
+ "ListAuthorizedViewsRequest",
+ "ListAuthorizedViewsResponse",
"ListBackupsRequest",
"ListBackupsResponse",
"ListClustersRequest",
@@ -145,28 +325,58 @@
"ListHotTabletsResponse",
"ListInstancesRequest",
"ListInstancesResponse",
+ "ListLogicalViewsRequest",
+ "ListLogicalViewsResponse",
+ "ListMaterializedViewsRequest",
+ "ListMaterializedViewsResponse",
+ "ListSchemaBundlesRequest",
+ "ListSchemaBundlesResponse",
"ListSnapshotsRequest",
"ListSnapshotsResponse",
"ListTablesRequest",
"ListTablesResponse",
+ "LogicalView",
+ "MaterializedView",
"ModifyColumnFamiliesRequest",
"OperationProgress",
"OptimizeRestoredTableMetadata",
"PartialUpdateClusterMetadata",
"PartialUpdateClusterRequest",
"PartialUpdateInstanceRequest",
+ "ProtoSchema",
"RestoreInfo",
"RestoreSourceType",
"RestoreTableMetadata",
"RestoreTableRequest",
+ "SchemaBundle",
"Snapshot",
"SnapshotTableMetadata",
"SnapshotTableRequest",
+ "StandardReadRemoteWrites",
"StorageType",
"Table",
+ "TieredStorageConfig",
+ "TieredStorageRule",
+ "Type",
+ "UndeleteTableMetadata",
+ "UndeleteTableRequest",
"UpdateAppProfileMetadata",
"UpdateAppProfileRequest",
+ "UpdateAuthorizedViewMetadata",
+ "UpdateAuthorizedViewRequest",
"UpdateBackupRequest",
"UpdateClusterMetadata",
"UpdateInstanceMetadata",
+ "UpdateLogicalViewMetadata",
+ "UpdateLogicalViewRequest",
+ "UpdateMaterializedViewMetadata",
+ "UpdateMaterializedViewRequest",
+ "UpdateSchemaBundleMetadata",
+ "UpdateSchemaBundleRequest",
+ "UpdateTableMetadata",
+ "UpdateTableRequest",
)
+
+from .overlay import * # noqa: F403
+
+__all__ += overlay.__all__ # noqa: F405
diff --git a/google/cloud/bigtable_admin_v2/gapic_metadata.json b/google/cloud/bigtable_admin_v2/gapic_metadata.json
index a843c42e0..9725d3384 100644
--- a/google/cloud/bigtable_admin_v2/gapic_metadata.json
+++ b/google/cloud/bigtable_admin_v2/gapic_metadata.json
@@ -25,6 +25,16 @@
"create_instance"
]
},
+ "CreateLogicalView": {
+ "methods": [
+ "create_logical_view"
+ ]
+ },
+ "CreateMaterializedView": {
+ "methods": [
+ "create_materialized_view"
+ ]
+ },
"DeleteAppProfile": {
"methods": [
"delete_app_profile"
@@ -40,6 +50,16 @@
"delete_instance"
]
},
+ "DeleteLogicalView": {
+ "methods": [
+ "delete_logical_view"
+ ]
+ },
+ "DeleteMaterializedView": {
+ "methods": [
+ "delete_materialized_view"
+ ]
+ },
"GetAppProfile": {
"methods": [
"get_app_profile"
@@ -60,6 +80,16 @@
"get_instance"
]
},
+ "GetLogicalView": {
+ "methods": [
+ "get_logical_view"
+ ]
+ },
+ "GetMaterializedView": {
+ "methods": [
+ "get_materialized_view"
+ ]
+ },
"ListAppProfiles": {
"methods": [
"list_app_profiles"
@@ -80,6 +110,16 @@
"list_instances"
]
},
+ "ListLogicalViews": {
+ "methods": [
+ "list_logical_views"
+ ]
+ },
+ "ListMaterializedViews": {
+ "methods": [
+ "list_materialized_views"
+ ]
+ },
"PartialUpdateCluster": {
"methods": [
"partial_update_cluster"
@@ -114,6 +154,16 @@
"methods": [
"update_instance"
]
+ },
+ "UpdateLogicalView": {
+ "methods": [
+ "update_logical_view"
+ ]
+ },
+ "UpdateMaterializedView": {
+ "methods": [
+ "update_materialized_view"
+ ]
}
}
},
@@ -135,6 +185,176 @@
"create_instance"
]
},
+ "CreateLogicalView": {
+ "methods": [
+ "create_logical_view"
+ ]
+ },
+ "CreateMaterializedView": {
+ "methods": [
+ "create_materialized_view"
+ ]
+ },
+ "DeleteAppProfile": {
+ "methods": [
+ "delete_app_profile"
+ ]
+ },
+ "DeleteCluster": {
+ "methods": [
+ "delete_cluster"
+ ]
+ },
+ "DeleteInstance": {
+ "methods": [
+ "delete_instance"
+ ]
+ },
+ "DeleteLogicalView": {
+ "methods": [
+ "delete_logical_view"
+ ]
+ },
+ "DeleteMaterializedView": {
+ "methods": [
+ "delete_materialized_view"
+ ]
+ },
+ "GetAppProfile": {
+ "methods": [
+ "get_app_profile"
+ ]
+ },
+ "GetCluster": {
+ "methods": [
+ "get_cluster"
+ ]
+ },
+ "GetIamPolicy": {
+ "methods": [
+ "get_iam_policy"
+ ]
+ },
+ "GetInstance": {
+ "methods": [
+ "get_instance"
+ ]
+ },
+ "GetLogicalView": {
+ "methods": [
+ "get_logical_view"
+ ]
+ },
+ "GetMaterializedView": {
+ "methods": [
+ "get_materialized_view"
+ ]
+ },
+ "ListAppProfiles": {
+ "methods": [
+ "list_app_profiles"
+ ]
+ },
+ "ListClusters": {
+ "methods": [
+ "list_clusters"
+ ]
+ },
+ "ListHotTablets": {
+ "methods": [
+ "list_hot_tablets"
+ ]
+ },
+ "ListInstances": {
+ "methods": [
+ "list_instances"
+ ]
+ },
+ "ListLogicalViews": {
+ "methods": [
+ "list_logical_views"
+ ]
+ },
+ "ListMaterializedViews": {
+ "methods": [
+ "list_materialized_views"
+ ]
+ },
+ "PartialUpdateCluster": {
+ "methods": [
+ "partial_update_cluster"
+ ]
+ },
+ "PartialUpdateInstance": {
+ "methods": [
+ "partial_update_instance"
+ ]
+ },
+ "SetIamPolicy": {
+ "methods": [
+ "set_iam_policy"
+ ]
+ },
+ "TestIamPermissions": {
+ "methods": [
+ "test_iam_permissions"
+ ]
+ },
+ "UpdateAppProfile": {
+ "methods": [
+ "update_app_profile"
+ ]
+ },
+ "UpdateCluster": {
+ "methods": [
+ "update_cluster"
+ ]
+ },
+ "UpdateInstance": {
+ "methods": [
+ "update_instance"
+ ]
+ },
+ "UpdateLogicalView": {
+ "methods": [
+ "update_logical_view"
+ ]
+ },
+ "UpdateMaterializedView": {
+ "methods": [
+ "update_materialized_view"
+ ]
+ }
+ }
+ },
+ "rest": {
+ "libraryClient": "BigtableInstanceAdminClient",
+ "rpcs": {
+ "CreateAppProfile": {
+ "methods": [
+ "create_app_profile"
+ ]
+ },
+ "CreateCluster": {
+ "methods": [
+ "create_cluster"
+ ]
+ },
+ "CreateInstance": {
+ "methods": [
+ "create_instance"
+ ]
+ },
+ "CreateLogicalView": {
+ "methods": [
+ "create_logical_view"
+ ]
+ },
+ "CreateMaterializedView": {
+ "methods": [
+ "create_materialized_view"
+ ]
+ },
"DeleteAppProfile": {
"methods": [
"delete_app_profile"
@@ -150,6 +370,16 @@
"delete_instance"
]
},
+ "DeleteLogicalView": {
+ "methods": [
+ "delete_logical_view"
+ ]
+ },
+ "DeleteMaterializedView": {
+ "methods": [
+ "delete_materialized_view"
+ ]
+ },
"GetAppProfile": {
"methods": [
"get_app_profile"
@@ -170,6 +400,16 @@
"get_instance"
]
},
+ "GetLogicalView": {
+ "methods": [
+ "get_logical_view"
+ ]
+ },
+ "GetMaterializedView": {
+ "methods": [
+ "get_materialized_view"
+ ]
+ },
"ListAppProfiles": {
"methods": [
"list_app_profiles"
@@ -190,6 +430,16 @@
"list_instances"
]
},
+ "ListLogicalViews": {
+ "methods": [
+ "list_logical_views"
+ ]
+ },
+ "ListMaterializedViews": {
+ "methods": [
+ "list_materialized_views"
+ ]
+ },
"PartialUpdateCluster": {
"methods": [
"partial_update_cluster"
@@ -224,6 +474,16 @@
"methods": [
"update_instance"
]
+ },
+ "UpdateLogicalView": {
+ "methods": [
+ "update_logical_view"
+ ]
+ },
+ "UpdateMaterializedView": {
+ "methods": [
+ "update_materialized_view"
+ ]
}
}
}
@@ -232,18 +492,33 @@
"BigtableTableAdmin": {
"clients": {
"grpc": {
- "libraryClient": "BigtableTableAdminClient",
+ "libraryClient": "BaseBigtableTableAdminClient",
"rpcs": {
"CheckConsistency": {
"methods": [
"check_consistency"
]
},
+ "CopyBackup": {
+ "methods": [
+ "copy_backup"
+ ]
+ },
+ "CreateAuthorizedView": {
+ "methods": [
+ "create_authorized_view"
+ ]
+ },
"CreateBackup": {
"methods": [
"create_backup"
]
},
+ "CreateSchemaBundle": {
+ "methods": [
+ "create_schema_bundle"
+ ]
+ },
"CreateTable": {
"methods": [
"create_table"
@@ -254,11 +529,21 @@
"create_table_from_snapshot"
]
},
+ "DeleteAuthorizedView": {
+ "methods": [
+ "delete_authorized_view"
+ ]
+ },
"DeleteBackup": {
"methods": [
"delete_backup"
]
},
+ "DeleteSchemaBundle": {
+ "methods": [
+ "delete_schema_bundle"
+ ]
+ },
"DeleteSnapshot": {
"methods": [
"delete_snapshot"
@@ -279,6 +564,11 @@
"generate_consistency_token"
]
},
+ "GetAuthorizedView": {
+ "methods": [
+ "get_authorized_view"
+ ]
+ },
"GetBackup": {
"methods": [
"get_backup"
@@ -289,6 +579,11 @@
"get_iam_policy"
]
},
+ "GetSchemaBundle": {
+ "methods": [
+ "get_schema_bundle"
+ ]
+ },
"GetSnapshot": {
"methods": [
"get_snapshot"
@@ -299,11 +594,21 @@
"get_table"
]
},
+ "ListAuthorizedViews": {
+ "methods": [
+ "list_authorized_views"
+ ]
+ },
"ListBackups": {
"methods": [
"list_backups"
]
},
+ "ListSchemaBundles": {
+ "methods": [
+ "list_schema_bundles"
+ ]
+ },
"ListSnapshots": {
"methods": [
"list_snapshots"
@@ -321,7 +626,7 @@
},
"RestoreTable": {
"methods": [
- "restore_table"
+ "_restore_table"
]
},
"SetIamPolicy": {
@@ -339,26 +644,241 @@
"test_iam_permissions"
]
},
+ "UndeleteTable": {
+ "methods": [
+ "undelete_table"
+ ]
+ },
+ "UpdateAuthorizedView": {
+ "methods": [
+ "update_authorized_view"
+ ]
+ },
"UpdateBackup": {
"methods": [
"update_backup"
]
+ },
+ "UpdateSchemaBundle": {
+ "methods": [
+ "update_schema_bundle"
+ ]
+ },
+ "UpdateTable": {
+ "methods": [
+ "update_table"
+ ]
}
}
},
"grpc-async": {
- "libraryClient": "BigtableTableAdminAsyncClient",
+ "libraryClient": "BaseBigtableTableAdminAsyncClient",
+ "rpcs": {
+ "CheckConsistency": {
+ "methods": [
+ "check_consistency"
+ ]
+ },
+ "CopyBackup": {
+ "methods": [
+ "copy_backup"
+ ]
+ },
+ "CreateAuthorizedView": {
+ "methods": [
+ "create_authorized_view"
+ ]
+ },
+ "CreateBackup": {
+ "methods": [
+ "create_backup"
+ ]
+ },
+ "CreateSchemaBundle": {
+ "methods": [
+ "create_schema_bundle"
+ ]
+ },
+ "CreateTable": {
+ "methods": [
+ "create_table"
+ ]
+ },
+ "CreateTableFromSnapshot": {
+ "methods": [
+ "create_table_from_snapshot"
+ ]
+ },
+ "DeleteAuthorizedView": {
+ "methods": [
+ "delete_authorized_view"
+ ]
+ },
+ "DeleteBackup": {
+ "methods": [
+ "delete_backup"
+ ]
+ },
+ "DeleteSchemaBundle": {
+ "methods": [
+ "delete_schema_bundle"
+ ]
+ },
+ "DeleteSnapshot": {
+ "methods": [
+ "delete_snapshot"
+ ]
+ },
+ "DeleteTable": {
+ "methods": [
+ "delete_table"
+ ]
+ },
+ "DropRowRange": {
+ "methods": [
+ "drop_row_range"
+ ]
+ },
+ "GenerateConsistencyToken": {
+ "methods": [
+ "generate_consistency_token"
+ ]
+ },
+ "GetAuthorizedView": {
+ "methods": [
+ "get_authorized_view"
+ ]
+ },
+ "GetBackup": {
+ "methods": [
+ "get_backup"
+ ]
+ },
+ "GetIamPolicy": {
+ "methods": [
+ "get_iam_policy"
+ ]
+ },
+ "GetSchemaBundle": {
+ "methods": [
+ "get_schema_bundle"
+ ]
+ },
+ "GetSnapshot": {
+ "methods": [
+ "get_snapshot"
+ ]
+ },
+ "GetTable": {
+ "methods": [
+ "get_table"
+ ]
+ },
+ "ListAuthorizedViews": {
+ "methods": [
+ "list_authorized_views"
+ ]
+ },
+ "ListBackups": {
+ "methods": [
+ "list_backups"
+ ]
+ },
+ "ListSchemaBundles": {
+ "methods": [
+ "list_schema_bundles"
+ ]
+ },
+ "ListSnapshots": {
+ "methods": [
+ "list_snapshots"
+ ]
+ },
+ "ListTables": {
+ "methods": [
+ "list_tables"
+ ]
+ },
+ "ModifyColumnFamilies": {
+ "methods": [
+ "modify_column_families"
+ ]
+ },
+ "RestoreTable": {
+ "methods": [
+ "_restore_table"
+ ]
+ },
+ "SetIamPolicy": {
+ "methods": [
+ "set_iam_policy"
+ ]
+ },
+ "SnapshotTable": {
+ "methods": [
+ "snapshot_table"
+ ]
+ },
+ "TestIamPermissions": {
+ "methods": [
+ "test_iam_permissions"
+ ]
+ },
+ "UndeleteTable": {
+ "methods": [
+ "undelete_table"
+ ]
+ },
+ "UpdateAuthorizedView": {
+ "methods": [
+ "update_authorized_view"
+ ]
+ },
+ "UpdateBackup": {
+ "methods": [
+ "update_backup"
+ ]
+ },
+ "UpdateSchemaBundle": {
+ "methods": [
+ "update_schema_bundle"
+ ]
+ },
+ "UpdateTable": {
+ "methods": [
+ "update_table"
+ ]
+ }
+ }
+ },
+ "rest": {
+ "libraryClient": "BaseBigtableTableAdminClient",
"rpcs": {
"CheckConsistency": {
"methods": [
"check_consistency"
]
},
+ "CopyBackup": {
+ "methods": [
+ "copy_backup"
+ ]
+ },
+ "CreateAuthorizedView": {
+ "methods": [
+ "create_authorized_view"
+ ]
+ },
"CreateBackup": {
"methods": [
"create_backup"
]
},
+ "CreateSchemaBundle": {
+ "methods": [
+ "create_schema_bundle"
+ ]
+ },
"CreateTable": {
"methods": [
"create_table"
@@ -369,11 +889,21 @@
"create_table_from_snapshot"
]
},
+ "DeleteAuthorizedView": {
+ "methods": [
+ "delete_authorized_view"
+ ]
+ },
"DeleteBackup": {
"methods": [
"delete_backup"
]
},
+ "DeleteSchemaBundle": {
+ "methods": [
+ "delete_schema_bundle"
+ ]
+ },
"DeleteSnapshot": {
"methods": [
"delete_snapshot"
@@ -394,6 +924,11 @@
"generate_consistency_token"
]
},
+ "GetAuthorizedView": {
+ "methods": [
+ "get_authorized_view"
+ ]
+ },
"GetBackup": {
"methods": [
"get_backup"
@@ -404,6 +939,11 @@
"get_iam_policy"
]
},
+ "GetSchemaBundle": {
+ "methods": [
+ "get_schema_bundle"
+ ]
+ },
"GetSnapshot": {
"methods": [
"get_snapshot"
@@ -414,11 +954,21 @@
"get_table"
]
},
+ "ListAuthorizedViews": {
+ "methods": [
+ "list_authorized_views"
+ ]
+ },
"ListBackups": {
"methods": [
"list_backups"
]
},
+ "ListSchemaBundles": {
+ "methods": [
+ "list_schema_bundles"
+ ]
+ },
"ListSnapshots": {
"methods": [
"list_snapshots"
@@ -436,7 +986,7 @@
},
"RestoreTable": {
"methods": [
- "restore_table"
+ "_restore_table"
]
},
"SetIamPolicy": {
@@ -454,10 +1004,30 @@
"test_iam_permissions"
]
},
+ "UndeleteTable": {
+ "methods": [
+ "undelete_table"
+ ]
+ },
+ "UpdateAuthorizedView": {
+ "methods": [
+ "update_authorized_view"
+ ]
+ },
"UpdateBackup": {
"methods": [
"update_backup"
]
+ },
+ "UpdateSchemaBundle": {
+ "methods": [
+ "update_schema_bundle"
+ ]
+ },
+ "UpdateTable": {
+ "methods": [
+ "update_table"
+ ]
}
}
}
diff --git a/google/cloud/bigtable_admin_v2/gapic_version.py b/google/cloud/bigtable_admin_v2/gapic_version.py
new file mode 100644
index 000000000..6d72a226d
--- /dev/null
+++ b/google/cloud/bigtable_admin_v2/gapic_version.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+# Copyright 2025 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.
+#
+__version__ = "2.35.0" # {x-release-please-version}
diff --git a/google/cloud/bigtable_admin_v2/overlay/__init__.py b/google/cloud/bigtable_admin_v2/overlay/__init__.py
new file mode 100644
index 000000000..f66c7f8dd
--- /dev/null
+++ b/google/cloud/bigtable_admin_v2/overlay/__init__.py
@@ -0,0 +1,49 @@
+# Copyright 2025 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.
+#
+# This directory and all its subdirectories are the only handwritten
+# components of the otherwise autogenerated google/cloud/bigtable/admin_v2.
+# The purpose of the overlay directory is to add additional functionality to
+# the autogenerated library while preserving its developer experience. These
+# handwritten additions currently consist of the following:
+#
+# 1. TODO: Document final GcRule design choice here
+# 2. An LRO class for restore_table that exposes an Operation for
+# OptimizeRestoreTable, if that LRO exists.
+# 3. New methods (wait_for_consistency and wait_for_replication) that return
+# a polling future class for automatically polling check_consistency.
+#
+# This directory is structured to mirror that of a typical autogenerated library (e.g.
+# services/types subdirectories), and the aforementioned handwritten additions are
+# currently implemented as either types under overlay/types or in methods in an overwritten
+# client class under overlay/services.
+
+from .types import (
+ AsyncRestoreTableOperation,
+ RestoreTableOperation,
+ WaitForConsistencyRequest,
+)
+
+from .services.bigtable_table_admin import (
+ BigtableTableAdminAsyncClient,
+ BigtableTableAdminClient,
+)
+
+__all__ = (
+ "AsyncRestoreTableOperation",
+ "RestoreTableOperation",
+ "BigtableTableAdminAsyncClient",
+ "BigtableTableAdminClient",
+ "WaitForConsistencyRequest",
+)
diff --git a/google/cloud/bigtable_admin_v2/overlay/services/__init__.py b/google/cloud/bigtable_admin_v2/overlay/services/__init__.py
new file mode 100644
index 000000000..ab7686e26
--- /dev/null
+++ b/google/cloud/bigtable_admin_v2/overlay/services/__init__.py
@@ -0,0 +1,13 @@
+# Copyright 2025 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.
diff --git a/google/cloud/bigtable_admin_v2/overlay/services/bigtable_table_admin/__init__.py b/google/cloud/bigtable_admin_v2/overlay/services/bigtable_table_admin/__init__.py
new file mode 100644
index 000000000..f80e3234f
--- /dev/null
+++ b/google/cloud/bigtable_admin_v2/overlay/services/bigtable_table_admin/__init__.py
@@ -0,0 +1,23 @@
+# Copyright 2025 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.
+
+# TODO: Add the async client after owlbot changes.
+
+from .async_client import BigtableTableAdminAsyncClient
+from .client import BigtableTableAdminClient
+
+__all__ = (
+ "BigtableTableAdminAsyncClient",
+ "BigtableTableAdminClient",
+)
diff --git a/google/cloud/bigtable_admin_v2/overlay/services/bigtable_table_admin/async_client.py b/google/cloud/bigtable_admin_v2/overlay/services/bigtable_table_admin/async_client.py
new file mode 100644
index 000000000..ee8e5757d
--- /dev/null
+++ b/google/cloud/bigtable_admin_v2/overlay/services/bigtable_table_admin/async_client.py
@@ -0,0 +1,375 @@
+# Copyright 2025 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.
+
+# -*- coding: utf-8 -*-
+# Copyright 2025 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 copy
+import functools
+
+from typing import Callable, Optional, Sequence, Tuple, Union
+from google.api_core import gapic_v1
+from google.api_core import retry as retries
+
+try:
+ OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None]
+except AttributeError: # pragma: NO COVER
+ OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore
+
+from google.api_core import client_options as client_options_lib
+from google.auth import credentials as ga_credentials # type: ignore
+
+from google.cloud.bigtable_admin_v2.types import bigtable_table_admin
+
+from google.cloud.bigtable_admin_v2.services.bigtable_table_admin import (
+ async_client as base_client,
+)
+from google.cloud.bigtable_admin_v2.services.bigtable_table_admin.transports.base import (
+ BigtableTableAdminTransport,
+)
+from google.cloud.bigtable_admin_v2.overlay.types import (
+ async_consistency,
+ async_restore_table,
+ wait_for_consistency_request,
+)
+
+from google.cloud.bigtable.gapic_version import __version__ as bigtable_version
+
+
+DEFAULT_CLIENT_INFO = copy.copy(base_client.DEFAULT_CLIENT_INFO)
+DEFAULT_CLIENT_INFO.client_library_version = f"{bigtable_version}-admin-overlay-async"
+
+
+class BigtableTableAdminAsyncClient(base_client.BaseBigtableTableAdminAsyncClient):
+ def __init__(
+ self,
+ *,
+ credentials: Optional[ga_credentials.Credentials] = None,
+ transport: Optional[
+ Union[
+ str,
+ BigtableTableAdminTransport,
+ Callable[..., BigtableTableAdminTransport],
+ ]
+ ] = "grpc_asyncio",
+ client_options: Optional[client_options_lib.ClientOptions] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ ) -> None:
+ """Instantiates the Bigtable table admin async client.
+
+ Args:
+ credentials (Optional[google.auth.credentials.Credentials]): The
+ authorization credentials to attach to requests. These
+ credentials identify the application to the service; if none
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+ transport (Optional[Union[str,BigtableTableAdminTransport,Callable[..., BigtableTableAdminTransport]]]):
+ The transport to use, or a Callable that constructs and returns a new transport to use.
+ If a Callable is given, it will be called with the same set of initialization
+ arguments as used in the BigtableTableAdminTransport constructor.
+ If set to None, a transport is chosen automatically.
+ client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]):
+ Custom options for the client.
+
+ 1. The ``api_endpoint`` property can be used to override the
+ default endpoint provided by the client when ``transport`` is
+ not explicitly provided. Only if this property is not set and
+ ``transport`` was not explicitly provided, the endpoint is
+ determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment
+ variable, which have one of the following values:
+ "always" (always use the default mTLS endpoint), "never" (always
+ use the default regular endpoint) and "auto" (auto-switch to the
+ default mTLS endpoint if client certificate is present; this is
+ the default value).
+
+ 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ is "true", then the ``client_cert_source`` property can be used
+ to provide a client certificate for mTLS transport. If
+ not provided, the default SSL client certificate will be used if
+ present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
+ set, no client certificate will be used.
+
+ 3. The ``universe_domain`` property can be used to override the
+ default "googleapis.com" universe. Note that ``api_endpoint``
+ property still takes precedence; and ``universe_domain`` is
+ currently not supported for mTLS.
+
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
+
+ Raises:
+ google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
+ creation failed for any reason.
+ """
+ super(BigtableTableAdminAsyncClient, self).__init__(
+ credentials=credentials,
+ transport=transport,
+ client_options=client_options,
+ client_info=client_info,
+ )
+
+ async def restore_table(
+ self,
+ request: Optional[Union[bigtable_table_admin.RestoreTableRequest, dict]] = None,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> async_restore_table.AsyncRestoreTableOperation:
+ r"""Create a new table by restoring from a completed backup. The
+ returned table :class:`long-running operation
+ `
+ can be used to track the progress of the operation, and to cancel it. The
+ :attr:`metadata ` field type is
+ :class:`RestoreTableMetadata `.
+ The :meth:`response ` type is
+ :class:`google.cloud.bigtable_admin_v2.types.Table`, if successful.
+
+ Additionally, the returned :class:`long-running-operation `
+ provides a method, :meth:`google.cloud.bigtable_admin_v2.overlay.types.async_restore_table.AsyncRestoreTableOperation.optimize_restore_table_operation` that
+ provides access to a :class:`google.api_core.operation_async.AsyncOperation` object representing the OptimizeRestoreTable long-running-operation
+ after the current one has completed.
+
+ .. code-block:: python
+
+ # This snippet should be regarded as a code template only.
+ #
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud.bigtable import admin_v2
+
+ async def sample_restore_table():
+ # Create a client
+ client = admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = admin_v2.RestoreTableRequest(
+ backup="backup_value",
+ parent="parent_value",
+ table_id="table_id_value",
+ )
+
+ # Make the request
+ operation = await client.restore_table(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = await operation.result()
+
+ # Handle the response
+ print(response)
+
+ # Handle LRO2
+ optimize_operation = await operation.optimize_restore_table_operation()
+
+ if optimize_operation:
+ print("Waiting for table optimization to complete...")
+
+ response = await optimize_operation.result()
+
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.types.RestoreTableRequest, dict]):
+ The request object. The request for
+ [RestoreTable][google.bigtable.admin.v2.BigtableTableAdmin.RestoreTable].
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.cloud.bigtable_admin_v2.overlay.types.async_restore_table.AsyncRestoreTableOperation:
+ An object representing a long-running operation.
+
+ The result type for the operation will be :class:`google.cloud.bigtable_admin_v2.types.Table` A collection of user data indexed by row, column, and timestamp.
+ Each table is served using the resources of its
+ parent cluster.
+ """
+ operation = await self._restore_table(
+ request=request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ restore_table_operation = async_restore_table.AsyncRestoreTableOperation(
+ self._client._transport.operations_client, operation
+ )
+ return restore_table_operation
+
+ async def wait_for_consistency(
+ self,
+ request: Optional[
+ Union[wait_for_consistency_request.WaitForConsistencyRequest, dict]
+ ] = None,
+ *,
+ name: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> bool:
+ r"""Blocks until the mutations for the specified Table that have been
+ made before the call have been replicated or reads using an app profile with `DataBoostIsolationReadOnly`
+ can see all writes committed before the token was created. This is done by generating
+ a consistency token for the Table, then polling :meth:`check_consistency`
+ for the specified table until the call returns True.
+
+ .. code-block:: python
+
+ # This snippet should be regarded as a code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud.bigtable import admin_v2
+
+ async def sample_wait_for_consistency():
+ # Create a client
+ client = admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = admin_v2.WaitForConsistencyRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ print("Waiting for operation to complete...")
+
+ response = await client.wait_for_replication(request=request)
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.overlay.types.WaitForConsistencyRequest, dict]):
+ The request object.
+ name (str):
+ Required. The unique name of the Table for which to
+ create a consistency token. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}``.
+
+ This corresponds to the ``name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ bool:
+ If the `standard_read_remote_writes` mode is specified in the request object, returns
+ `True` after the mutations of the specified table have been fully replicated. If the
+ `data_boost_read_local_writes` mode is specified in the request object, returns `True`
+ after reads using an app profile with `DataBoostIsolationReadOnly` can see all writes
+ committed before the token was created.
+
+ Raises:
+ google.api_core.GoogleAPICallError: If the operation errors or if
+ the timeout is reached before the operation completes.
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(
+ request, wait_for_consistency_request.WaitForConsistencyRequest
+ ):
+ request = wait_for_consistency_request.WaitForConsistencyRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if name is not None:
+ request.name = name
+
+ # Generate the consistency token.
+ generate_consistency_token_request = (
+ bigtable_table_admin.GenerateConsistencyTokenRequest(
+ name=request.name,
+ )
+ )
+
+ generate_consistency_response = await self.generate_consistency_token(
+ generate_consistency_token_request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Create the CheckConsistencyRequest object.
+ check_consistency_request = bigtable_table_admin.CheckConsistencyRequest(
+ name=request.name,
+ consistency_token=generate_consistency_response.consistency_token,
+ )
+
+ # Since the default values of StandardReadRemoteWrites and DataBoostReadLocalWrites evaluate to
+ # False in proto plus, we cannot do a simple "if request.standard_read_remote_writes" to check
+ # whether or not that field is defined in the original request object.
+ mode_oneof_field = request._pb.WhichOneof("mode")
+ if mode_oneof_field:
+ setattr(
+ check_consistency_request,
+ mode_oneof_field,
+ getattr(request, mode_oneof_field),
+ )
+
+ check_consistency_call = functools.partial(
+ self.check_consistency,
+ check_consistency_request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Block and wait until the polling harness returns True.
+ check_consistency_future = (
+ async_consistency._AsyncCheckConsistencyPollingFuture(
+ check_consistency_call
+ )
+ )
+ return await check_consistency_future.result()
diff --git a/google/cloud/bigtable_admin_v2/overlay/services/bigtable_table_admin/client.py b/google/cloud/bigtable_admin_v2/overlay/services/bigtable_table_admin/client.py
new file mode 100644
index 000000000..1b6770b10
--- /dev/null
+++ b/google/cloud/bigtable_admin_v2/overlay/services/bigtable_table_admin/client.py
@@ -0,0 +1,373 @@
+# Copyright 2025 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.
+
+# -*- coding: utf-8 -*-
+# Copyright 2025 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 copy
+import functools
+
+from typing import Callable, Optional, Sequence, Tuple, Union
+from google.api_core import gapic_v1
+from google.api_core import retry as retries
+
+try:
+ OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None]
+except AttributeError: # pragma: NO COVER
+ OptionalRetry = Union[retries.Retry, object, None] # type: ignore
+
+from google.api_core import client_options as client_options_lib
+from google.auth import credentials as ga_credentials # type: ignore
+
+from google.cloud.bigtable_admin_v2.types import bigtable_table_admin
+
+from google.cloud.bigtable_admin_v2.services.bigtable_table_admin import (
+ client as base_client,
+)
+from google.cloud.bigtable_admin_v2.services.bigtable_table_admin.transports.base import (
+ BigtableTableAdminTransport,
+)
+from google.cloud.bigtable_admin_v2.overlay.types import (
+ consistency,
+ restore_table,
+ wait_for_consistency_request,
+)
+
+from google.cloud.bigtable.gapic_version import __version__ as bigtable_version
+
+
+DEFAULT_CLIENT_INFO = copy.copy(base_client.DEFAULT_CLIENT_INFO)
+DEFAULT_CLIENT_INFO.client_library_version = f"{bigtable_version}-admin-overlay"
+
+
+class BigtableTableAdminClient(base_client.BaseBigtableTableAdminClient):
+ def __init__(
+ self,
+ *,
+ credentials: Optional[ga_credentials.Credentials] = None,
+ transport: Optional[
+ Union[
+ str,
+ BigtableTableAdminTransport,
+ Callable[..., BigtableTableAdminTransport],
+ ]
+ ] = None,
+ client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ ) -> None:
+ """Instantiates the Bigtable table admin client.
+
+ Args:
+ credentials (Optional[google.auth.credentials.Credentials]): The
+ authorization credentials to attach to requests. These
+ credentials identify the application to the service; if none
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+ transport (Optional[Union[str,BigtableTableAdminTransport,Callable[..., BigtableTableAdminTransport]]]):
+ The transport to use, or a Callable that constructs and returns a new transport.
+ If a Callable is given, it will be called with the same set of initialization
+ arguments as used in the BigtableTableAdminTransport constructor.
+ If set to None, a transport is chosen automatically.
+ client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]):
+ Custom options for the client.
+
+ 1. The ``api_endpoint`` property can be used to override the
+ default endpoint provided by the client when ``transport`` is
+ not explicitly provided. Only if this property is not set and
+ ``transport`` was not explicitly provided, the endpoint is
+ determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment
+ variable, which have one of the following values:
+ "always" (always use the default mTLS endpoint), "never" (always
+ use the default regular endpoint) and "auto" (auto-switch to the
+ default mTLS endpoint if client certificate is present; this is
+ the default value).
+
+ 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ is "true", then the ``client_cert_source`` property can be used
+ to provide a client certificate for mTLS transport. If
+ not provided, the default SSL client certificate will be used if
+ present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
+ set, no client certificate will be used.
+
+ 3. The ``universe_domain`` property can be used to override the
+ default "googleapis.com" universe. Note that the ``api_endpoint``
+ property still takes precedence; and ``universe_domain`` is
+ currently not supported for mTLS.
+
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
+
+ Raises:
+ google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
+ creation failed for any reason.
+ """
+ super(BigtableTableAdminClient, self).__init__(
+ credentials=credentials,
+ transport=transport,
+ client_options=client_options,
+ client_info=client_info,
+ )
+
+ def restore_table(
+ self,
+ request: Optional[Union[bigtable_table_admin.RestoreTableRequest, dict]] = None,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> restore_table.RestoreTableOperation:
+ r"""Create a new table by restoring from a completed backup. The
+ returned table :class:`long-running operation
+ `
+ can be used to track the progress of the operation, and to cancel it. The
+ :attr:`metadata ` field type is
+ :class:`RestoreTableMetadata `.
+ The :meth:`response ` type is
+ :class:`google.cloud.bigtable_admin_v2.types.Table`, if successful.
+
+ Additionally, the returned :class:`long-running-operation `
+ provides a method, :meth:`google.cloud.bigtable_admin_v2.overlay.types.restore_table.RestoreTableOperation.optimize_restore_table_operation` that
+ provides access to a :class:`google.api_core.operation.Operation` object representing the OptimizeRestoreTable long-running-operation
+ after the current one has completed.
+
+ .. code-block:: python
+
+ # This snippet should be regarded as a code template only.
+ #
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud.bigtable import admin_v2
+
+ def sample_restore_table():
+ # Create a client
+ client = admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = admin_v2.RestoreTableRequest(
+ backup="backup_value",
+ parent="parent_value",
+ table_id="table_id_value",
+ )
+
+ # Make the request
+ operation = client.restore_table(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = operation.result()
+
+ # Handle the response
+ print(response)
+
+ # Handle LRO2
+ optimize_operation = operation.optimize_restore_table_operation()
+
+ if optimize_operation:
+ print("Waiting for table optimization to complete...")
+
+ response = optimize_operation.result()
+
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.types.RestoreTableRequest, dict]):
+ The request object. The request for
+ [RestoreTable][google.bigtable.admin.v2.BigtableTableAdmin.RestoreTable].
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.cloud.bigtable_admin_v2.overlay.types.restore_table.RestoreTableOperation:
+ An object representing a long-running operation.
+
+ The result type for the operation will be :class:`google.cloud.bigtable_admin_v2.types.Table` A collection of user data indexed by row, column, and timestamp.
+ Each table is served using the resources of its
+ parent cluster.
+ """
+ operation = self._restore_table(
+ request=request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ restore_table_operation = restore_table.RestoreTableOperation(
+ self._transport.operations_client, operation
+ )
+ return restore_table_operation
+
+ def wait_for_consistency(
+ self,
+ request: Optional[
+ Union[wait_for_consistency_request.WaitForConsistencyRequest, dict]
+ ] = None,
+ *,
+ name: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> bool:
+ r"""Blocks until the mutations for the specified Table that have been
+ made before the call have been replicated or reads using an app profile with `DataBoostIsolationReadOnly`
+ can see all writes committed before the token was created. This is done by generating
+ a consistency token for the Table, then polling :meth:`check_consistency`
+ for the specified table until the call returns True.
+
+ .. code-block:: python
+
+ # This snippet should be regarded as a code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud.bigtable import admin_v2
+
+ def sample_wait_for_consistency():
+ # Create a client
+ client = admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = admin_v2.WaitForConsistencyRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ print("Waiting for operation to complete...")
+
+ response = client.wait_for_replication(request=request)
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.overlay.types.WaitForConsistencyRequest, dict]):
+ The request object.
+ name (str):
+ Required. The unique name of the Table for which to
+ create a consistency token. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}``.
+
+ This corresponds to the ``name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ bool:
+ If the `standard_read_remote_writes` mode is specified in the request object, returns
+ `True` after the mutations of the specified table have been fully replicated. If the
+ `data_boost_read_local_writes` mode is specified in the request object, returns `True`
+ after reads using an app profile with `DataBoostIsolationReadOnly` can see all writes
+ committed before the token was created.
+
+ Raises:
+ google.api_core.GoogleAPICallError: If the operation errors or if
+ the timeout is reached before the operation completes.
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(
+ request, wait_for_consistency_request.WaitForConsistencyRequest
+ ):
+ request = wait_for_consistency_request.WaitForConsistencyRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if name is not None:
+ request.name = name
+
+ # Generate the consistency token.
+ generate_consistency_token_request = (
+ bigtable_table_admin.GenerateConsistencyTokenRequest(
+ name=request.name,
+ )
+ )
+
+ generate_consistency_response = self.generate_consistency_token(
+ generate_consistency_token_request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Create the CheckConsistencyRequest object.
+ check_consistency_request = bigtable_table_admin.CheckConsistencyRequest(
+ name=request.name,
+ consistency_token=generate_consistency_response.consistency_token,
+ )
+
+ # Since the default values of StandardReadRemoteWrites and DataBoostReadLocalWrites evaluate to
+ # False in proto plus, we cannot do a simple "if request.standard_read_remote_writes" to check
+ # whether or not that field is defined in the original request object.
+ mode_oneof_field = request._pb.WhichOneof("mode")
+ if mode_oneof_field:
+ setattr(
+ check_consistency_request,
+ mode_oneof_field,
+ getattr(request, mode_oneof_field),
+ )
+
+ check_consistency_call = functools.partial(
+ self.check_consistency,
+ check_consistency_request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Block and wait until the polling harness returns True.
+ check_consistency_future = consistency._CheckConsistencyPollingFuture(
+ check_consistency_call
+ )
+ return check_consistency_future.result()
diff --git a/google/cloud/bigtable_admin_v2/overlay/types/__init__.py b/google/cloud/bigtable_admin_v2/overlay/types/__init__.py
new file mode 100644
index 000000000..16b032ac4
--- /dev/null
+++ b/google/cloud/bigtable_admin_v2/overlay/types/__init__.py
@@ -0,0 +1,31 @@
+# Copyright 2025 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.
+
+from .async_restore_table import (
+ AsyncRestoreTableOperation,
+)
+
+from .restore_table import (
+ RestoreTableOperation,
+)
+
+from .wait_for_consistency_request import (
+ WaitForConsistencyRequest,
+)
+
+__all__ = (
+ "AsyncRestoreTableOperation",
+ "RestoreTableOperation",
+ "WaitForConsistencyRequest",
+)
diff --git a/google/cloud/bigtable_admin_v2/overlay/types/async_consistency.py b/google/cloud/bigtable_admin_v2/overlay/types/async_consistency.py
new file mode 100644
index 000000000..0703940d5
--- /dev/null
+++ b/google/cloud/bigtable_admin_v2/overlay/types/async_consistency.py
@@ -0,0 +1,104 @@
+# Copyright 2025 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.
+
+from typing import Awaitable, Union, Callable
+
+from google.api_core.future import async_future
+from google.api_core import gapic_v1
+from google.api_core import retry as retries
+from google.cloud.bigtable_admin_v2.types import bigtable_table_admin
+
+try:
+ OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None]
+except AttributeError: # pragma: NO COVER
+ OptionalRetry = Union[retries.Retry, object, None] # type: ignore
+
+
+# The consistency check could take a very long time, so we wait indefinitely.
+DEFAULT_RETRY = async_future.DEFAULT_RETRY.with_timeout(None)
+
+
+class _AsyncCheckConsistencyPollingFuture(async_future.AsyncFuture):
+ """A Future that polls an underlying `check_consistency` operation until it returns True.
+
+ **This class should not be instantiated by users** and should only be instantiated by the admin
+ client's
+ :meth:`google.cloud.bigtable_admin_v2.overlay.services.bigtable_table_admin.AsyncBigtableTableAdminClient.wait_for_consistency`
+ or
+ :meth:`google.cloud.bigtable_admin_v2.overlay.services.bigtable_table_admin.AsyncBigtableTableAdminClient.wait_for_replication`
+ methods.
+
+ Args:
+ check_consistency_call(Callable[
+ [Optional[google.api_core.retry.Retry],
+ google.cloud.bigtable_admin_v2.types.CheckConsistencyResponse]):
+ A :meth:`check_consistency
+ `
+ call from the admin client. The call should fix every user parameter except for retry,
+ which will be done via :meth:`functools.partial`.
+ default_retry(Optional[google.api_core.retry.Retry]): The `retry` parameter passed in to either
+ :meth:`wait_for_consistency
+ `
+ or :meth:`wait_for_replication
+ `
+ retry (google.api_core.retry.AsyncRetry): The retry configuration used
+ when polling. This can be used to control how often :meth:`done`
+ is polled. Regardless of the retry's ``deadline``, it will be
+ overridden by the ``timeout`` argument to :meth:`result`.
+ """
+
+ def __init__(
+ self,
+ check_consistency_call: Callable[
+ [OptionalRetry], Awaitable[bigtable_table_admin.CheckConsistencyResponse]
+ ],
+ retry: retries.AsyncRetry = DEFAULT_RETRY,
+ **kwargs
+ ):
+ super(_AsyncCheckConsistencyPollingFuture, self).__init__(retry=retry, **kwargs)
+
+ # Done is called with two different scenarios, retry is specified or not specified.
+ # API_call will be a functools partial with everything except retry specified because of
+ # that.
+ self._check_consistency_call = check_consistency_call
+
+ async def done(self, retry: OptionalRetry = None):
+ """Polls the underlying `check_consistency` call to see if the future is complete.
+
+ Args:
+ retry (google.api_core.retry.Retry): (Optional) How to retry the
+ polling RPC (to not be confused with polling configuration. See
+ the documentation for :meth:`result `
+ for details).
+
+ Returns:
+ bool: True if the future is complete, False otherwise.
+ """
+ if self._future.done():
+ return True
+
+ try:
+ check_consistency_response = await self._check_consistency_call()
+ if check_consistency_response.consistent:
+ self.set_result(True)
+
+ return check_consistency_response.consistent
+ except Exception as e:
+ self.set_exception(e)
+
+ def cancel(self):
+ raise NotImplementedError("Cannot cancel consistency token operation")
+
+ def cancelled(self):
+ raise NotImplementedError("Cannot cancel consistency token operation")
diff --git a/google/cloud/bigtable_admin_v2/overlay/types/async_restore_table.py b/google/cloud/bigtable_admin_v2/overlay/types/async_restore_table.py
new file mode 100644
index 000000000..9edfb4963
--- /dev/null
+++ b/google/cloud/bigtable_admin_v2/overlay/types/async_restore_table.py
@@ -0,0 +1,99 @@
+# Copyright 2025 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.
+
+from typing import Optional
+
+from google.api_core import exceptions
+from google.api_core import operation_async
+from google.protobuf import empty_pb2
+
+from google.cloud.bigtable_admin_v2.types import OptimizeRestoredTableMetadata
+
+
+class AsyncRestoreTableOperation(operation_async.AsyncOperation):
+ """A Future for interacting with Bigtable Admin's RestoreTable Long-Running Operation.
+
+ This is needed to expose a potential long-running operation that might run after this operation
+ finishes, OptimizeRestoreTable. This is exposed via the the :meth:`optimize_restore_table_operation`
+ method.
+
+ **This class should not be instantiated by users** and should only be instantiated by the admin
+ client's :meth:`restore_table
+ `
+ method.
+
+ Args:
+ operations_client (google.api_core.operations_v1.AbstractOperationsClient): The operations
+ client from the admin client class's transport.
+ restore_table_operation (google.api_core.operation_async.AsyncOperation): A
+ :class:`google.api_core.operation_async.AsyncOperation`
+ instance resembling a RestoreTable long-running operation
+ """
+
+ def __init__(
+ self, operations_client, restore_table_operation: operation_async.AsyncOperation
+ ):
+ self._operations_client = operations_client
+ self._optimize_restored_table_operation = None
+ super().__init__(
+ restore_table_operation._operation,
+ restore_table_operation._refresh,
+ restore_table_operation._cancel,
+ restore_table_operation._result_type,
+ restore_table_operation._metadata_type,
+ retry=restore_table_operation._retry,
+ )
+
+ async def optimize_restored_table_operation(
+ self,
+ ) -> Optional[operation_async.AsyncOperation]:
+ """Gets the OptimizeRestoredTable long-running operation that runs after this operation finishes.
+ The current operation might not trigger a follow-up OptimizeRestoredTable operation, in which case, this
+ method will return `None`.
+ This method must not be called before the parent restore_table operation is complete.
+ Returns:
+ An object representing a long-running operation, or None if there is no OptimizeRestoredTable operation
+ after this one.
+ Raises:
+ RuntimeError: raised when accessed before the restore_table operation is complete
+
+ Raises:
+ google.api_core.GoogleAPIError: raised when accessed before the restore_table operation is complete
+ """
+ if not await self.done():
+ raise exceptions.GoogleAPIError(
+ "optimize_restored_table operation can't be accessed until the restore_table operation is complete"
+ )
+
+ if self._optimize_restored_table_operation is not None:
+ return self._optimize_restored_table_operation
+
+ operation_name = self.metadata.optimize_table_operation_name
+
+ # When the RestoreTable operation finishes, it might not necessarily trigger
+ # an optimize operation.
+ if operation_name:
+ gapic_operation = await self._operations_client.get_operation(
+ name=operation_name
+ )
+ self._optimize_restored_table_operation = operation_async.from_gapic(
+ gapic_operation,
+ self._operations_client,
+ empty_pb2.Empty,
+ metadata_type=OptimizeRestoredTableMetadata,
+ )
+ return self._optimize_restored_table_operation
+ else:
+ # no optimize operation found
+ return None
diff --git a/google/cloud/bigtable_admin_v2/overlay/types/consistency.py b/google/cloud/bigtable_admin_v2/overlay/types/consistency.py
new file mode 100644
index 000000000..63a110975
--- /dev/null
+++ b/google/cloud/bigtable_admin_v2/overlay/types/consistency.py
@@ -0,0 +1,101 @@
+# Copyright 2025 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.
+
+from typing import Union, Callable
+
+from google.api_core.future import polling
+from google.api_core import gapic_v1
+from google.api_core import retry as retries
+from google.cloud.bigtable_admin_v2.types import bigtable_table_admin
+
+try:
+ OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None]
+except AttributeError: # pragma: NO COVER
+ OptionalRetry = Union[retries.Retry, object, None] # type: ignore
+
+
+# The consistency check could take a very long time, so we wait indefinitely.
+DEFAULT_RETRY = polling.DEFAULT_POLLING.with_timeout(None)
+
+
+class _CheckConsistencyPollingFuture(polling.PollingFuture):
+ """A Future that polls an underlying `check_consistency` operation until it returns True.
+
+ **This class should not be instantiated by users** and should only be instantiated by the admin
+ client's
+ :meth:`google.cloud.bigtable_admin_v2.overlay.services.bigtable_table_admin.BigtableTableAdminClient.wait_for_consistency`
+ or
+ :meth:`google.cloud.bigtable_admin_v2.overlay.services.bigtable_table_admin.BigtableTableAdminClient.wait_for_replication`
+ methods.
+
+ Args:
+ check_consistency_call(Callable[
+ [Optional[google.api_core.retry.Retry],
+ google.cloud.bigtable_admin_v2.types.CheckConsistencyResponse]):
+ A :meth:`check_consistency
+ `
+ call from the admin client. The call should fix every user parameter,
+ which will be done via :meth:`functools.partial`.
+ polling (google.api_core.retry.Retry): The configuration used for polling.
+ This parameter controls how often :meth:`done` is polled. If the
+ ``timeout`` argument is specified in the :meth:`result
+ ` method it will
+ override the ``polling.timeout`` property.
+ """
+
+ def __init__(
+ self,
+ check_consistency_call: Callable[
+ [OptionalRetry], bigtable_table_admin.CheckConsistencyResponse
+ ],
+ polling: retries.Retry = DEFAULT_RETRY,
+ **kwargs
+ ):
+ super(_CheckConsistencyPollingFuture, self).__init__(polling=polling, **kwargs)
+
+ # Done is called with two different scenarios, retry is specified or not specified.
+ # API_call will be a functools partial with everything except retry specified because of
+ # that.
+ self._check_consistency_call = check_consistency_call
+
+ def done(self, retry: OptionalRetry = None):
+ """Polls the underlying `check_consistency` call to see if the future is complete.
+
+ Args:
+ retry (google.api_core.retry.Retry): (Optional) How to retry the
+ polling RPC (to not be confused with polling configuration. See
+ the documentation for :meth:`result `
+ for details).
+
+ Returns:
+ bool: True if the future is complete, False otherwise.
+ """
+
+ if self._result_set:
+ return True
+
+ try:
+ check_consistency_response = self._check_consistency_call()
+ if check_consistency_response.consistent:
+ self.set_result(True)
+
+ return check_consistency_response.consistent
+ except Exception as e:
+ self.set_exception(e)
+
+ def cancel(self):
+ raise NotImplementedError("Cannot cancel consistency token operation")
+
+ def cancelled(self):
+ raise NotImplementedError("Cannot cancel consistency token operation")
diff --git a/google/cloud/bigtable_admin_v2/overlay/types/restore_table.py b/google/cloud/bigtable_admin_v2/overlay/types/restore_table.py
new file mode 100644
index 000000000..84c9c5d91
--- /dev/null
+++ b/google/cloud/bigtable_admin_v2/overlay/types/restore_table.py
@@ -0,0 +1,102 @@
+# Copyright 2025 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.
+
+from typing import Optional
+
+from google.api_core import exceptions
+from google.api_core import operation
+from google.protobuf import empty_pb2
+
+from google.cloud.bigtable_admin_v2.types import OptimizeRestoredTableMetadata
+
+
+class RestoreTableOperation(operation.Operation):
+ """A Future for interacting with Bigtable Admin's RestoreTable Long-Running Operation.
+
+ This is needed to expose a potential long-running operation that might run after this operation
+ finishes, OptimizeRestoreTable. This is exposed via the the :meth:`optimize_restore_table_operation`
+ method.
+
+ **This class should not be instantiated by users** and should only be instantiated by the admin
+ client's :meth:`restore_table
+ `
+ method.
+
+ Args:
+ operations_client (google.api_core.operations_v1.AbstractOperationsClient): The operations
+ client from the admin client class's transport.
+ restore_table_operation (google.api_core.operation.Operation): A :class:`google.api_core.operation.Operation`
+ instance resembling a RestoreTable long-running operation
+ """
+
+ def __init__(self, operations_client, restore_table_operation: operation.Operation):
+ self._operations_client = operations_client
+ self._optimize_restored_table_operation = None
+ super().__init__(
+ restore_table_operation._operation,
+ restore_table_operation._refresh,
+ restore_table_operation._cancel,
+ restore_table_operation._result_type,
+ restore_table_operation._metadata_type,
+ polling=restore_table_operation._polling,
+ )
+
+ def optimize_restored_table_operation(self) -> Optional[operation.Operation]:
+ """Gets the OptimizeRestoredTable long-running operation that runs after this operation finishes.
+
+ This must not be called before the parent restore_table operation is complete. You can guarantee
+ this happening by calling this function after this class's :meth:`google.api_core.operation.Operation.result`
+ method.
+
+ The follow-up operation has
+ :attr:`metadata ` type
+ :class:`OptimizeRestoredTableMetadata
+ `
+ and no return value, but can be waited for with `result`.
+
+ The current operation might not trigger a follow-up OptimizeRestoredTable operation, in which case, this
+ method will return `None`.
+
+ Returns:
+ Optional[google.api_core.operation.Operation]:
+ An object representing a long-running operation, or None if there is no OptimizeRestoredTable operation
+ after this one.
+
+ Raises:
+ google.api_core.GoogleAPIError: raised when accessed before the restore_table operation is complete
+ """
+ if not self.done():
+ raise exceptions.GoogleAPIError(
+ "optimize_restored_table operation can't be accessed until the restore_table operation is complete"
+ )
+
+ if self._optimize_restored_table_operation is not None:
+ return self._optimize_restored_table_operation
+
+ operation_name = self.metadata.optimize_table_operation_name
+
+ # When the RestoreTable operation finishes, it might not necessarily trigger
+ # an optimize operation.
+ if operation_name:
+ gapic_operation = self._operations_client.get_operation(name=operation_name)
+ self._optimize_restored_table_operation = operation.from_gapic(
+ gapic_operation,
+ self._operations_client,
+ empty_pb2.Empty,
+ metadata_type=OptimizeRestoredTableMetadata,
+ )
+ return self._optimize_restored_table_operation
+ else:
+ # no optimize operation found
+ return None
diff --git a/google/cloud/bigtable_admin_v2/overlay/types/wait_for_consistency_request.py b/google/cloud/bigtable_admin_v2/overlay/types/wait_for_consistency_request.py
new file mode 100644
index 000000000..51070230a
--- /dev/null
+++ b/google/cloud/bigtable_admin_v2/overlay/types/wait_for_consistency_request.py
@@ -0,0 +1,85 @@
+# -*- coding: utf-8 -*-
+# Copyright 2025 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 proto
+
+from google.cloud.bigtable_admin_v2.types import bigtable_table_admin
+
+__protobuf__ = proto.module(
+ package="google.bigtable.admin.v2",
+ manifest={
+ "WaitForConsistencyRequest",
+ },
+)
+
+
+# The WaitForConsistencyRequest object is not a real proto. It is a wrapper
+# class intended for the handwritten method wait_for_consistency. It is
+# constructed by extending a Proto Plus message class to get a developer
+# experience closest to that of an autogenerated GAPIC method, and to allow
+# developers to manipulate the wrapper class like they would a request proto
+# for an autogenerated call.
+class WaitForConsistencyRequest(proto.Message):
+ """Wrapper class for encapsulating parameters for the `wait_for_consistency` method in both
+ :class:`google.cloud.bigtable_admin_v2.overlay.services.bigtable_table_admin.client.BigtableTableAdminClient`
+ and :class:`google.cloud.bigtable_admin_v2.overlay.services.bigtable_table_admin.async_client.BigtableTableAdmiAsyncClient`.
+
+
+ This message has `oneof`_ fields (mutually exclusive fields).
+ For each oneof, at most one member field can be set at the same time.
+ Setting any member of the oneof automatically clears all other
+ members.
+
+ .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields
+
+ Attributes:
+ name (str):
+ Required. The unique name of the Table for which to check
+ replication consistency. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}``.
+ standard_read_remote_writes (google.cloud.bigtable_admin_v2.types.StandardReadRemoteWrites):
+ Checks that reads using an app profile with
+ ``StandardIsolation`` can see all writes committed before
+ the token was created, even if the read and write target
+ different clusters.
+
+ This field is a member of `oneof`_ ``mode``.
+ data_boost_read_local_writes (google.cloud.bigtable_admin_v2.types.DataBoostReadLocalWrites):
+ Checks that reads using an app profile with
+ ``DataBoostIsolationReadOnly`` can see all writes committed
+ before the token was created, but only if the read and write
+ target the same cluster.
+
+ This field is a member of `oneof`_ ``mode``.
+ """
+
+ name: str = proto.Field(proto.STRING, number=1)
+ standard_read_remote_writes: bigtable_table_admin.StandardReadRemoteWrites = (
+ proto.Field(
+ proto.MESSAGE,
+ number=2,
+ oneof="mode",
+ message=bigtable_table_admin.StandardReadRemoteWrites,
+ )
+ )
+ data_boost_read_local_writes: bigtable_table_admin.DataBoostReadLocalWrites = (
+ proto.Field(
+ proto.MESSAGE,
+ number=3,
+ oneof="mode",
+ message=bigtable_table_admin.DataBoostReadLocalWrites,
+ )
+ )
diff --git a/google/cloud/bigtable_admin_v2/services/__init__.py b/google/cloud/bigtable_admin_v2/services/__init__.py
index e8e1c3845..cbf94b283 100644
--- a/google/cloud/bigtable_admin_v2/services/__init__.py
+++ b/google/cloud/bigtable_admin_v2/services/__init__.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/__init__.py b/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/__init__.py
index 1fb10736e..20ac9e4fc 100644
--- a/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/__init__.py
+++ b/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/__init__.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/async_client.py b/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/async_client.py
index 9853efdb4..632496543 100644
--- a/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/async_client.py
+++ b/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/async_client.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -13,23 +13,37 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+import logging as std_logging
from collections import OrderedDict
-import functools
import re
-from typing import Dict, Mapping, Optional, Sequence, Tuple, Type, Union
-import pkg_resources
+from typing import (
+ Dict,
+ Callable,
+ Mapping,
+ MutableMapping,
+ MutableSequence,
+ Optional,
+ Sequence,
+ Tuple,
+ Type,
+ Union,
+)
+
+from google.cloud.bigtable_admin_v2 import gapic_version as package_version
from google.api_core.client_options import ClientOptions
from google.api_core import exceptions as core_exceptions
from google.api_core import gapic_v1
-from google.api_core import retry as retries
+from google.api_core import retry_async as retries
from google.auth import credentials as ga_credentials # type: ignore
from google.oauth2 import service_account # type: ignore
+import google.protobuf
+
try:
- OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault]
+ OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None]
except AttributeError: # pragma: NO COVER
- OptionalRetry = Union[retries.Retry, object] # type: ignore
+ OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore
from google.api_core import operation # type: ignore
from google.api_core import operation_async # type: ignore
@@ -46,6 +60,15 @@
from .transports.grpc_asyncio import BigtableInstanceAdminGrpcAsyncIOTransport
from .client import BigtableInstanceAdminClient
+try:
+ from google.api_core import client_logging # type: ignore
+
+ CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER
+except ImportError: # pragma: NO COVER
+ CLIENT_LOGGING_SUPPORTED = False
+
+_LOGGER = std_logging.getLogger(__name__)
+
class BigtableInstanceAdminAsyncClient:
"""Service for creating, configuring, and deleting Cloud
@@ -56,8 +79,12 @@ class BigtableInstanceAdminAsyncClient:
_client: BigtableInstanceAdminClient
+ # Copy defaults from the synchronous client for use here.
+ # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead.
DEFAULT_ENDPOINT = BigtableInstanceAdminClient.DEFAULT_ENDPOINT
DEFAULT_MTLS_ENDPOINT = BigtableInstanceAdminClient.DEFAULT_MTLS_ENDPOINT
+ _DEFAULT_ENDPOINT_TEMPLATE = BigtableInstanceAdminClient._DEFAULT_ENDPOINT_TEMPLATE
+ _DEFAULT_UNIVERSE = BigtableInstanceAdminClient._DEFAULT_UNIVERSE
app_profile_path = staticmethod(BigtableInstanceAdminClient.app_profile_path)
parse_app_profile_path = staticmethod(
@@ -75,6 +102,16 @@ class BigtableInstanceAdminAsyncClient:
)
instance_path = staticmethod(BigtableInstanceAdminClient.instance_path)
parse_instance_path = staticmethod(BigtableInstanceAdminClient.parse_instance_path)
+ logical_view_path = staticmethod(BigtableInstanceAdminClient.logical_view_path)
+ parse_logical_view_path = staticmethod(
+ BigtableInstanceAdminClient.parse_logical_view_path
+ )
+ materialized_view_path = staticmethod(
+ BigtableInstanceAdminClient.materialized_view_path
+ )
+ parse_materialized_view_path = staticmethod(
+ BigtableInstanceAdminClient.parse_materialized_view_path
+ )
table_path = staticmethod(BigtableInstanceAdminClient.table_path)
parse_table_path = staticmethod(BigtableInstanceAdminClient.parse_table_path)
common_billing_account_path = staticmethod(
@@ -153,7 +190,7 @@ def get_mtls_endpoint_and_cert_source(
The API endpoint is determined in the following order:
(1) if `client_options.api_endpoint` if provided, use the provided one.
(2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the
- default mTLS endpoint; if the environment variabel is "never", use the default API
+ default mTLS endpoint; if the environment variable is "never", use the default API
endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise
use the default API endpoint.
@@ -182,20 +219,42 @@ def transport(self) -> BigtableInstanceAdminTransport:
"""
return self._client.transport
- get_transport_class = functools.partial(
- type(BigtableInstanceAdminClient).get_transport_class,
- type(BigtableInstanceAdminClient),
- )
+ @property
+ def api_endpoint(self):
+ """Return the API endpoint used by the client instance.
+
+ Returns:
+ str: The API endpoint used by the client instance.
+ """
+ return self._client._api_endpoint
+
+ @property
+ def universe_domain(self) -> str:
+ """Return the universe domain used by the client instance.
+
+ Returns:
+ str: The universe domain used
+ by the client instance.
+ """
+ return self._client._universe_domain
+
+ get_transport_class = BigtableInstanceAdminClient.get_transport_class
def __init__(
self,
*,
- credentials: ga_credentials.Credentials = None,
- transport: Union[str, BigtableInstanceAdminTransport] = "grpc_asyncio",
- client_options: ClientOptions = None,
+ credentials: Optional[ga_credentials.Credentials] = None,
+ transport: Optional[
+ Union[
+ str,
+ BigtableInstanceAdminTransport,
+ Callable[..., BigtableInstanceAdminTransport],
+ ]
+ ] = "grpc_asyncio",
+ client_options: Optional[ClientOptions] = None,
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
- """Instantiates the bigtable instance admin client.
+ """Instantiates the bigtable instance admin async client.
Args:
credentials (Optional[google.auth.credentials.Credentials]): The
@@ -203,26 +262,43 @@ def __init__(
credentials identify the application to the service; if none
are specified, the client will attempt to ascertain the
credentials from the environment.
- transport (Union[str, ~.BigtableInstanceAdminTransport]): The
- transport to use. If set to None, a transport is chosen
- automatically.
- client_options (ClientOptions): Custom options for the client. It
- won't take effect if a ``transport`` instance is provided.
- (1) The ``api_endpoint`` property can be used to override the
- default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
- environment variable can also be used to override the endpoint:
+ transport (Optional[Union[str,BigtableInstanceAdminTransport,Callable[..., BigtableInstanceAdminTransport]]]):
+ The transport to use, or a Callable that constructs and returns a new transport to use.
+ If a Callable is given, it will be called with the same set of initialization
+ arguments as used in the BigtableInstanceAdminTransport constructor.
+ If set to None, a transport is chosen automatically.
+ client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]):
+ Custom options for the client.
+
+ 1. The ``api_endpoint`` property can be used to override the
+ default endpoint provided by the client when ``transport`` is
+ not explicitly provided. Only if this property is not set and
+ ``transport`` was not explicitly provided, the endpoint is
+ determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment
+ variable, which have one of the following values:
"always" (always use the default mTLS endpoint), "never" (always
- use the default regular endpoint) and "auto" (auto switch to the
- default mTLS endpoint if client certificate is present, this is
- the default value). However, the ``api_endpoint`` property takes
- precedence if provided.
- (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ use the default regular endpoint) and "auto" (auto-switch to the
+ default mTLS endpoint if client certificate is present; this is
+ the default value).
+
+ 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
is "true", then the ``client_cert_source`` property can be used
- to provide client certificate for mutual TLS transport. If
+ to provide a client certificate for mTLS transport. If
not provided, the default SSL client certificate will be used if
present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
set, no client certificate will be used.
+ 3. The ``universe_domain`` property can be used to override the
+ default "googleapis.com" universe. Note that ``api_endpoint``
+ property still takes precedence; and ``universe_domain`` is
+ currently not supported for mTLS.
+
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
+
Raises:
google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
creation failed for any reason.
@@ -234,17 +310,41 @@ def __init__(
client_info=client_info,
)
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ std_logging.DEBUG
+ ): # pragma: NO COVER
+ _LOGGER.debug(
+ "Created client `google.bigtable.admin_v2.BigtableInstanceAdminAsyncClient`.",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "universeDomain": getattr(
+ self._client._transport._credentials, "universe_domain", ""
+ ),
+ "credentialsType": f"{type(self._client._transport._credentials).__module__}.{type(self._client._transport._credentials).__qualname__}",
+ "credentialsInfo": getattr(
+ self.transport._credentials, "get_cred_info", lambda: None
+ )(),
+ }
+ if hasattr(self._client._transport, "_credentials")
+ else {
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "credentialsType": None,
+ },
+ )
+
async def create_instance(
self,
- request: Union[bigtable_instance_admin.CreateInstanceRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_instance_admin.CreateInstanceRequest, dict]
+ ] = None,
*,
- parent: str = None,
- instance_id: str = None,
- instance: gba_instance.Instance = None,
- clusters: Mapping[str, gba_instance.Cluster] = None,
+ parent: Optional[str] = None,
+ instance_id: Optional[str] = None,
+ instance: Optional[gba_instance.Instance] = None,
+ clusters: Optional[MutableMapping[str, gba_instance.Cluster]] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> operation_async.AsyncOperation:
r"""Create an instance within a project.
@@ -254,8 +354,43 @@ async def create_instance(
scaled. If cluster_config.cluster_autoscaling_config is
non-empty, then autoscaling is enabled.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_create_instance():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ instance = bigtable_admin_v2.Instance()
+ instance.display_name = "display_name_value"
+
+ request = bigtable_admin_v2.CreateInstanceRequest(
+ parent="parent_value",
+ instance_id="instance_id_value",
+ instance=instance,
+ )
+
+ # Make the request
+ operation = client.create_instance(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = (await operation).result()
+
+ # Handle the response
+ print(response)
+
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.CreateInstanceRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.CreateInstanceRequest, dict]]):
The request object. Request message for
BigtableInstanceAdmin.CreateInstance.
parent (:class:`str`):
@@ -281,22 +416,23 @@ async def create_instance(
This corresponds to the ``instance`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- clusters (:class:`Mapping[str, google.cloud.bigtable_admin_v2.types.Cluster]`):
+ clusters (:class:`MutableMapping[str, google.cloud.bigtable_admin_v2.types.Cluster]`):
Required. The clusters to be created within the
instance, mapped by desired cluster ID, e.g., just
``mycluster`` rather than
``projects/myproject/instances/myinstance/clusters/mycluster``.
Fields marked ``OutputOnly`` must be left blank.
- Currently, at most four clusters can be specified.
This corresponds to the ``clusters`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.api_core.operation_async.AsyncOperation:
@@ -310,16 +446,22 @@ async def create_instance(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([parent, instance_id, instance, clusters])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent, instance_id, instance, clusters]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_instance_admin.CreateInstanceRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_instance_admin.CreateInstanceRequest):
+ request = bigtable_instance_admin.CreateInstanceRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
@@ -335,11 +477,9 @@ async def create_instance(
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.create_instance,
- default_timeout=300.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.create_instance
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -347,6 +487,9 @@ async def create_instance(
gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -368,17 +511,45 @@ async def create_instance(
async def get_instance(
self,
- request: Union[bigtable_instance_admin.GetInstanceRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_instance_admin.GetInstanceRequest, dict]
+ ] = None,
*,
- name: str = None,
+ name: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> instance.Instance:
r"""Gets information about an instance.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_get_instance():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.GetInstanceRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ response = await client.get_instance(request=request)
+
+ # Handle the response
+ print(response)
+
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.GetInstanceRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.GetInstanceRequest, dict]]):
The request object. Request message for
BigtableInstanceAdmin.GetInstance.
name (:class:`str`):
@@ -389,11 +560,13 @@ async def get_instance(
This corresponds to the ``name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_admin_v2.types.Instance:
@@ -405,16 +578,22 @@ async def get_instance(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_instance_admin.GetInstanceRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_instance_admin.GetInstanceRequest):
+ request = bigtable_instance_admin.GetInstanceRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
@@ -423,21 +602,9 @@ async def get_instance(
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.get_instance,
- default_retry=retries.Retry(
- initial=1.0,
- maximum=60.0,
- multiplier=2,
- predicate=retries.if_exception_type(
- core_exceptions.DeadlineExceeded,
- core_exceptions.ServiceUnavailable,
- ),
- deadline=60.0,
- ),
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.get_instance
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -445,6 +612,9 @@ async def get_instance(
gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -458,17 +628,45 @@ async def get_instance(
async def list_instances(
self,
- request: Union[bigtable_instance_admin.ListInstancesRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_instance_admin.ListInstancesRequest, dict]
+ ] = None,
*,
- parent: str = None,
+ parent: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> bigtable_instance_admin.ListInstancesResponse:
r"""Lists information about instances in a project.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_list_instances():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.ListInstancesRequest(
+ parent="parent_value",
+ )
+
+ # Make the request
+ response = await client.list_instances(request=request)
+
+ # Handle the response
+ print(response)
+
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.ListInstancesRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.ListInstancesRequest, dict]]):
The request object. Request message for
BigtableInstanceAdmin.ListInstances.
parent (:class:`str`):
@@ -479,11 +677,13 @@ async def list_instances(
This corresponds to the ``parent`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_admin_v2.types.ListInstancesResponse:
@@ -492,16 +692,22 @@ async def list_instances(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([parent])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_instance_admin.ListInstancesRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_instance_admin.ListInstancesRequest):
+ request = bigtable_instance_admin.ListInstancesRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
@@ -510,21 +716,9 @@ async def list_instances(
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.list_instances,
- default_retry=retries.Retry(
- initial=1.0,
- maximum=60.0,
- multiplier=2,
- predicate=retries.if_exception_type(
- core_exceptions.DeadlineExceeded,
- core_exceptions.ServiceUnavailable,
- ),
- deadline=60.0,
- ),
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.list_instances
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -532,6 +726,9 @@ async def list_instances(
gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -545,30 +742,58 @@ async def list_instances(
async def update_instance(
self,
- request: Union[instance.Instance, dict] = None,
+ request: Optional[Union[instance.Instance, dict]] = None,
*,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> instance.Instance:
r"""Updates an instance within a project. This method
updates only the display name and type for an Instance.
To update other Instance properties, such as labels, use
PartialUpdateInstance.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_update_instance():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.Instance(
+ display_name="display_name_value",
+ )
+
+ # Make the request
+ response = await client.update_instance(request=request)
+
+ # Handle the response
+ print(response)
+
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.Instance, dict]):
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.Instance, dict]]):
The request object. A collection of Bigtable
[Tables][google.bigtable.admin.v2.Table] and the
resources that serve them. All tables in an instance are
served from all
[Clusters][google.bigtable.admin.v2.Cluster] in the
instance.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_admin_v2.types.Instance:
@@ -580,25 +805,16 @@ async def update_instance(
"""
# Create or coerce a protobuf request object.
- request = instance.Instance(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, instance.Instance):
+ request = instance.Instance(request)
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.update_instance,
- default_retry=retries.Retry(
- initial=1.0,
- maximum=60.0,
- multiplier=2,
- predicate=retries.if_exception_type(
- core_exceptions.DeadlineExceeded,
- core_exceptions.ServiceUnavailable,
- ),
- deadline=60.0,
- ),
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.update_instance
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -606,6 +822,9 @@ async def update_instance(
gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -619,22 +838,55 @@ async def update_instance(
async def partial_update_instance(
self,
- request: Union[
- bigtable_instance_admin.PartialUpdateInstanceRequest, dict
+ request: Optional[
+ Union[bigtable_instance_admin.PartialUpdateInstanceRequest, dict]
] = None,
*,
- instance: gba_instance.Instance = None,
- update_mask: field_mask_pb2.FieldMask = None,
+ instance: Optional[gba_instance.Instance] = None,
+ update_mask: Optional[field_mask_pb2.FieldMask] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> operation_async.AsyncOperation:
r"""Partially updates an instance within a project. This
method can modify all fields of an Instance and is the
preferred way to update an Instance.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_partial_update_instance():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ instance = bigtable_admin_v2.Instance()
+ instance.display_name = "display_name_value"
+
+ request = bigtable_admin_v2.PartialUpdateInstanceRequest(
+ instance=instance,
+ )
+
+ # Make the request
+ operation = client.partial_update_instance(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = (await operation).result()
+
+ # Handle the response
+ print(response)
+
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.PartialUpdateInstanceRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.PartialUpdateInstanceRequest, dict]]):
The request object. Request message for
BigtableInstanceAdmin.PartialUpdateInstance.
instance (:class:`google.cloud.bigtable_admin_v2.types.Instance`):
@@ -652,11 +904,13 @@ async def partial_update_instance(
This corresponds to the ``update_mask`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.api_core.operation_async.AsyncOperation:
@@ -670,16 +924,24 @@ async def partial_update_instance(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([instance, update_mask])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [instance, update_mask]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_instance_admin.PartialUpdateInstanceRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(
+ request, bigtable_instance_admin.PartialUpdateInstanceRequest
+ ):
+ request = bigtable_instance_admin.PartialUpdateInstanceRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
@@ -690,21 +952,9 @@ async def partial_update_instance(
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.partial_update_instance,
- default_retry=retries.Retry(
- initial=1.0,
- maximum=60.0,
- multiplier=2,
- predicate=retries.if_exception_type(
- core_exceptions.DeadlineExceeded,
- core_exceptions.ServiceUnavailable,
- ),
- deadline=60.0,
- ),
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.partial_update_instance
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -714,6 +964,9 @@ async def partial_update_instance(
),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -735,17 +988,42 @@ async def partial_update_instance(
async def delete_instance(
self,
- request: Union[bigtable_instance_admin.DeleteInstanceRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_instance_admin.DeleteInstanceRequest, dict]
+ ] = None,
*,
- name: str = None,
+ name: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> None:
r"""Delete an instance from a project.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_delete_instance():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.DeleteInstanceRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ await client.delete_instance(request=request)
+
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.DeleteInstanceRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.DeleteInstanceRequest, dict]]):
The request object. Request message for
BigtableInstanceAdmin.DeleteInstance.
name (:class:`str`):
@@ -756,23 +1034,31 @@ async def delete_instance(
This corresponds to the ``name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_instance_admin.DeleteInstanceRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_instance_admin.DeleteInstanceRequest):
+ request = bigtable_instance_admin.DeleteInstanceRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
@@ -781,11 +1067,9 @@ async def delete_instance(
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.delete_instance,
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.delete_instance
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -793,6 +1077,9 @@ async def delete_instance(
gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
await rpc(
request,
@@ -803,14 +1090,16 @@ async def delete_instance(
async def create_cluster(
self,
- request: Union[bigtable_instance_admin.CreateClusterRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_instance_admin.CreateClusterRequest, dict]
+ ] = None,
*,
- parent: str = None,
- cluster_id: str = None,
- cluster: instance.Cluster = None,
+ parent: Optional[str] = None,
+ cluster_id: Optional[str] = None,
+ cluster: Optional[instance.Cluster] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> operation_async.AsyncOperation:
r"""Creates a cluster within an instance.
@@ -820,8 +1109,39 @@ async def create_cluster(
scaled. If cluster_config.cluster_autoscaling_config is
non-empty, then autoscaling is enabled.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_create_cluster():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.CreateClusterRequest(
+ parent="parent_value",
+ cluster_id="cluster_id_value",
+ )
+
+ # Make the request
+ operation = client.create_cluster(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = (await operation).result()
+
+ # Handle the response
+ print(response)
+
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.CreateClusterRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.CreateClusterRequest, dict]]):
The request object. Request message for
BigtableInstanceAdmin.CreateCluster.
parent (:class:`str`):
@@ -848,11 +1168,13 @@ async def create_cluster(
This corresponds to the ``cluster`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.api_core.operation_async.AsyncOperation:
@@ -865,16 +1187,22 @@ async def create_cluster(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([parent, cluster_id, cluster])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent, cluster_id, cluster]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_instance_admin.CreateClusterRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_instance_admin.CreateClusterRequest):
+ request = bigtable_instance_admin.CreateClusterRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
@@ -887,11 +1215,9 @@ async def create_cluster(
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.create_cluster,
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.create_cluster
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -899,6 +1225,9 @@ async def create_cluster(
gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -920,17 +1249,45 @@ async def create_cluster(
async def get_cluster(
self,
- request: Union[bigtable_instance_admin.GetClusterRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_instance_admin.GetClusterRequest, dict]
+ ] = None,
*,
- name: str = None,
+ name: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> instance.Cluster:
r"""Gets information about a cluster.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_get_cluster():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.GetClusterRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ response = await client.get_cluster(request=request)
+
+ # Handle the response
+ print(response)
+
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.GetClusterRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.GetClusterRequest, dict]]):
The request object. Request message for
BigtableInstanceAdmin.GetCluster.
name (:class:`str`):
@@ -941,11 +1298,13 @@ async def get_cluster(
This corresponds to the ``name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_admin_v2.types.Cluster:
@@ -956,16 +1315,22 @@ async def get_cluster(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_instance_admin.GetClusterRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_instance_admin.GetClusterRequest):
+ request = bigtable_instance_admin.GetClusterRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
@@ -974,21 +1339,9 @@ async def get_cluster(
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.get_cluster,
- default_retry=retries.Retry(
- initial=1.0,
- maximum=60.0,
- multiplier=2,
- predicate=retries.if_exception_type(
- core_exceptions.DeadlineExceeded,
- core_exceptions.ServiceUnavailable,
- ),
- deadline=60.0,
- ),
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.get_cluster
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -996,6 +1349,9 @@ async def get_cluster(
gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -1009,17 +1365,45 @@ async def get_cluster(
async def list_clusters(
self,
- request: Union[bigtable_instance_admin.ListClustersRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_instance_admin.ListClustersRequest, dict]
+ ] = None,
*,
- parent: str = None,
+ parent: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> bigtable_instance_admin.ListClustersResponse:
r"""Lists information about clusters in an instance.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_list_clusters():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.ListClustersRequest(
+ parent="parent_value",
+ )
+
+ # Make the request
+ response = await client.list_clusters(request=request)
+
+ # Handle the response
+ print(response)
+
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.ListClustersRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.ListClustersRequest, dict]]):
The request object. Request message for
BigtableInstanceAdmin.ListClusters.
parent (:class:`str`):
@@ -1032,11 +1416,13 @@ async def list_clusters(
This corresponds to the ``parent`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_admin_v2.types.ListClustersResponse:
@@ -1045,16 +1431,22 @@ async def list_clusters(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([parent])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_instance_admin.ListClustersRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_instance_admin.ListClustersRequest):
+ request = bigtable_instance_admin.ListClustersRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
@@ -1063,21 +1455,9 @@ async def list_clusters(
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.list_clusters,
- default_retry=retries.Retry(
- initial=1.0,
- maximum=60.0,
- multiplier=2,
- predicate=retries.if_exception_type(
- core_exceptions.DeadlineExceeded,
- core_exceptions.ServiceUnavailable,
- ),
- deadline=60.0,
- ),
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.list_clusters
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -1085,6 +1465,9 @@ async def list_clusters(
gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -1098,11 +1481,11 @@ async def list_clusters(
async def update_cluster(
self,
- request: Union[instance.Cluster, dict] = None,
+ request: Optional[Union[instance.Cluster, dict]] = None,
*,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> operation_async.AsyncOperation:
r"""Updates a cluster within an instance.
@@ -1110,17 +1493,48 @@ async def update_cluster(
cluster_config.cluster_autoscaling_config. In order to update
it, you must use PartialUpdateCluster.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_update_cluster():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.Cluster(
+ )
+
+ # Make the request
+ operation = client.update_cluster(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = (await operation).result()
+
+ # Handle the response
+ print(response)
+
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.Cluster, dict]):
- The request object. A resizable group of nodes in a
- particular cloud location, capable of serving all
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.Cluster, dict]]):
+ The request object. A resizable group of nodes in a particular cloud
+ location, capable of serving all
[Tables][google.bigtable.admin.v2.Table] in the parent
[Instance][google.bigtable.admin.v2.Instance].
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.api_core.operation_async.AsyncOperation:
@@ -1133,25 +1547,16 @@ async def update_cluster(
"""
# Create or coerce a protobuf request object.
- request = instance.Cluster(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, instance.Cluster):
+ request = instance.Cluster(request)
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.update_cluster,
- default_retry=retries.Retry(
- initial=1.0,
- maximum=60.0,
- multiplier=2,
- predicate=retries.if_exception_type(
- core_exceptions.DeadlineExceeded,
- core_exceptions.ServiceUnavailable,
- ),
- deadline=60.0,
- ),
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.update_cluster
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -1159,6 +1564,9 @@ async def update_cluster(
gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -1180,15 +1588,15 @@ async def update_cluster(
async def partial_update_cluster(
self,
- request: Union[
- bigtable_instance_admin.PartialUpdateClusterRequest, dict
+ request: Optional[
+ Union[bigtable_instance_admin.PartialUpdateClusterRequest, dict]
] = None,
*,
- cluster: instance.Cluster = None,
- update_mask: field_mask_pb2.FieldMask = None,
+ cluster: Optional[instance.Cluster] = None,
+ update_mask: Optional[field_mask_pb2.FieldMask] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> operation_async.AsyncOperation:
r"""Partially updates a cluster within a project. This method is the
preferred way to update a Cluster.
@@ -1205,8 +1613,37 @@ async def partial_update_cluster(
cluster_config.cluster_autoscaling_config, and explicitly set a
serve_node count via the update_mask.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_partial_update_cluster():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.PartialUpdateClusterRequest(
+ )
+
+ # Make the request
+ operation = client.partial_update_cluster(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = (await operation).result()
+
+ # Handle the response
+ print(response)
+
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.PartialUpdateClusterRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.PartialUpdateClusterRequest, dict]]):
The request object. Request message for
BigtableInstanceAdmin.PartialUpdateCluster.
cluster (:class:`google.cloud.bigtable_admin_v2.types.Cluster`):
@@ -1223,11 +1660,13 @@ async def partial_update_cluster(
This corresponds to the ``update_mask`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.api_core.operation_async.AsyncOperation:
@@ -1240,16 +1679,22 @@ async def partial_update_cluster(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([cluster, update_mask])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [cluster, update_mask]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_instance_admin.PartialUpdateClusterRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_instance_admin.PartialUpdateClusterRequest):
+ request = bigtable_instance_admin.PartialUpdateClusterRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
@@ -1260,11 +1705,9 @@ async def partial_update_cluster(
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.partial_update_cluster,
- default_timeout=None,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.partial_update_cluster
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -1274,6 +1717,9 @@ async def partial_update_cluster(
),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -1295,17 +1741,42 @@ async def partial_update_cluster(
async def delete_cluster(
self,
- request: Union[bigtable_instance_admin.DeleteClusterRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_instance_admin.DeleteClusterRequest, dict]
+ ] = None,
*,
- name: str = None,
+ name: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> None:
r"""Deletes a cluster from an instance.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_delete_cluster():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.DeleteClusterRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ await client.delete_cluster(request=request)
+
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.DeleteClusterRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.DeleteClusterRequest, dict]]):
The request object. Request message for
BigtableInstanceAdmin.DeleteCluster.
name (:class:`str`):
@@ -1316,23 +1787,31 @@ async def delete_cluster(
This corresponds to the ``name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_instance_admin.DeleteClusterRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_instance_admin.DeleteClusterRequest):
+ request = bigtable_instance_admin.DeleteClusterRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
@@ -1341,11 +1820,9 @@ async def delete_cluster(
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.delete_cluster,
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.delete_cluster
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -1353,6 +1830,9 @@ async def delete_cluster(
gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
await rpc(
request,
@@ -1363,19 +1843,52 @@ async def delete_cluster(
async def create_app_profile(
self,
- request: Union[bigtable_instance_admin.CreateAppProfileRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_instance_admin.CreateAppProfileRequest, dict]
+ ] = None,
*,
- parent: str = None,
- app_profile_id: str = None,
- app_profile: instance.AppProfile = None,
+ parent: Optional[str] = None,
+ app_profile_id: Optional[str] = None,
+ app_profile: Optional[instance.AppProfile] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> instance.AppProfile:
r"""Creates an app profile within an instance.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_create_app_profile():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ app_profile = bigtable_admin_v2.AppProfile()
+ app_profile.priority = "PRIORITY_HIGH"
+
+ request = bigtable_admin_v2.CreateAppProfileRequest(
+ parent="parent_value",
+ app_profile_id="app_profile_id_value",
+ app_profile=app_profile,
+ )
+
+ # Make the request
+ response = await client.create_app_profile(request=request)
+
+ # Handle the response
+ print(response)
+
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.CreateAppProfileRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.CreateAppProfileRequest, dict]]):
The request object. Request message for
BigtableInstanceAdmin.CreateAppProfile.
parent (:class:`str`):
@@ -1402,11 +1915,13 @@ async def create_app_profile(
This corresponds to the ``app_profile`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_admin_v2.types.AppProfile:
@@ -1416,16 +1931,22 @@ async def create_app_profile(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([parent, app_profile_id, app_profile])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent, app_profile_id, app_profile]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_instance_admin.CreateAppProfileRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_instance_admin.CreateAppProfileRequest):
+ request = bigtable_instance_admin.CreateAppProfileRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
@@ -1438,11 +1959,9 @@ async def create_app_profile(
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.create_app_profile,
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.create_app_profile
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -1450,6 +1969,9 @@ async def create_app_profile(
gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -1463,17 +1985,45 @@ async def create_app_profile(
async def get_app_profile(
self,
- request: Union[bigtable_instance_admin.GetAppProfileRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_instance_admin.GetAppProfileRequest, dict]
+ ] = None,
*,
- name: str = None,
+ name: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> instance.AppProfile:
r"""Gets information about an app profile.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_get_app_profile():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.GetAppProfileRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ response = await client.get_app_profile(request=request)
+
+ # Handle the response
+ print(response)
+
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.GetAppProfileRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.GetAppProfileRequest, dict]]):
The request object. Request message for
BigtableInstanceAdmin.GetAppProfile.
name (:class:`str`):
@@ -1484,11 +2034,13 @@ async def get_app_profile(
This corresponds to the ``name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_admin_v2.types.AppProfile:
@@ -1498,16 +2050,22 @@ async def get_app_profile(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_instance_admin.GetAppProfileRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_instance_admin.GetAppProfileRequest):
+ request = bigtable_instance_admin.GetAppProfileRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
@@ -1516,21 +2074,9 @@ async def get_app_profile(
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.get_app_profile,
- default_retry=retries.Retry(
- initial=1.0,
- maximum=60.0,
- multiplier=2,
- predicate=retries.if_exception_type(
- core_exceptions.DeadlineExceeded,
- core_exceptions.ServiceUnavailable,
- ),
- deadline=60.0,
- ),
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.get_app_profile
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -1538,6 +2084,9 @@ async def get_app_profile(
gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -1551,17 +2100,46 @@ async def get_app_profile(
async def list_app_profiles(
self,
- request: Union[bigtable_instance_admin.ListAppProfilesRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_instance_admin.ListAppProfilesRequest, dict]
+ ] = None,
*,
- parent: str = None,
+ parent: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> pagers.ListAppProfilesAsyncPager:
r"""Lists information about app profiles in an instance.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_list_app_profiles():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.ListAppProfilesRequest(
+ parent="parent_value",
+ )
+
+ # Make the request
+ page_result = client.list_app_profiles(request=request)
+
+ # Handle the response
+ async for response in page_result:
+ print(response)
+
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.ListAppProfilesRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.ListAppProfilesRequest, dict]]):
The request object. Request message for
BigtableInstanceAdmin.ListAppProfiles.
parent (:class:`str`):
@@ -1575,11 +2153,13 @@ async def list_app_profiles(
This corresponds to the ``parent`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_admin_v2.services.bigtable_instance_admin.pagers.ListAppProfilesAsyncPager:
@@ -1591,16 +2171,22 @@ async def list_app_profiles(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([parent])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_instance_admin.ListAppProfilesRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_instance_admin.ListAppProfilesRequest):
+ request = bigtable_instance_admin.ListAppProfilesRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
@@ -1609,21 +2195,9 @@ async def list_app_profiles(
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.list_app_profiles,
- default_retry=retries.Retry(
- initial=1.0,
- maximum=60.0,
- multiplier=2,
- predicate=retries.if_exception_type(
- core_exceptions.DeadlineExceeded,
- core_exceptions.ServiceUnavailable,
- ),
- deadline=60.0,
- ),
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.list_app_profiles
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -1631,6 +2205,9 @@ async def list_app_profiles(
gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -1645,6 +2222,8 @@ async def list_app_profiles(
method=rpc,
request=request,
response=response,
+ retry=retry,
+ timeout=timeout,
metadata=metadata,
)
@@ -1653,18 +2232,53 @@ async def list_app_profiles(
async def update_app_profile(
self,
- request: Union[bigtable_instance_admin.UpdateAppProfileRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_instance_admin.UpdateAppProfileRequest, dict]
+ ] = None,
*,
- app_profile: instance.AppProfile = None,
- update_mask: field_mask_pb2.FieldMask = None,
+ app_profile: Optional[instance.AppProfile] = None,
+ update_mask: Optional[field_mask_pb2.FieldMask] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> operation_async.AsyncOperation:
r"""Updates an app profile within an instance.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_update_app_profile():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ app_profile = bigtable_admin_v2.AppProfile()
+ app_profile.priority = "PRIORITY_HIGH"
+
+ request = bigtable_admin_v2.UpdateAppProfileRequest(
+ app_profile=app_profile,
+ )
+
+ # Make the request
+ operation = client.update_app_profile(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = (await operation).result()
+
+ # Handle the response
+ print(response)
+
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.UpdateAppProfileRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.UpdateAppProfileRequest, dict]]):
The request object. Request message for
BigtableInstanceAdmin.UpdateAppProfile.
app_profile (:class:`google.cloud.bigtable_admin_v2.types.AppProfile`):
@@ -1682,11 +2296,13 @@ async def update_app_profile(
This corresponds to the ``update_mask`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.api_core.operation_async.AsyncOperation:
@@ -1697,16 +2313,22 @@ async def update_app_profile(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([app_profile, update_mask])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [app_profile, update_mask]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_instance_admin.UpdateAppProfileRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_instance_admin.UpdateAppProfileRequest):
+ request = bigtable_instance_admin.UpdateAppProfileRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
@@ -1717,21 +2339,9 @@ async def update_app_profile(
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.update_app_profile,
- default_retry=retries.Retry(
- initial=1.0,
- maximum=60.0,
- multiplier=2,
- predicate=retries.if_exception_type(
- core_exceptions.DeadlineExceeded,
- core_exceptions.ServiceUnavailable,
- ),
- deadline=60.0,
- ),
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.update_app_profile
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -1741,6 +2351,9 @@ async def update_app_profile(
),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -1762,17 +2375,44 @@ async def update_app_profile(
async def delete_app_profile(
self,
- request: Union[bigtable_instance_admin.DeleteAppProfileRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_instance_admin.DeleteAppProfileRequest, dict]
+ ] = None,
*,
- name: str = None,
+ name: Optional[str] = None,
+ ignore_warnings: Optional[bool] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> None:
r"""Deletes an app profile from an instance.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_delete_app_profile():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.DeleteAppProfileRequest(
+ name="name_value",
+ ignore_warnings=True,
+ )
+
+ # Make the request
+ await client.delete_app_profile(request=request)
+
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.DeleteAppProfileRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.DeleteAppProfileRequest, dict]]):
The request object. Request message for
BigtableInstanceAdmin.DeleteAppProfile.
name (:class:`str`):
@@ -1783,36 +2423,51 @@ async def delete_app_profile(
This corresponds to the ``name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ ignore_warnings (:class:`bool`):
+ Required. If true, ignore safety
+ checks when deleting the app profile.
+
+ This corresponds to the ``ignore_warnings`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name, ignore_warnings]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_instance_admin.DeleteAppProfileRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_instance_admin.DeleteAppProfileRequest):
+ request = bigtable_instance_admin.DeleteAppProfileRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
if name is not None:
request.name = name
+ if ignore_warnings is not None:
+ request.ignore_warnings = ignore_warnings
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.delete_app_profile,
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.delete_app_profile
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -1820,6 +2475,9 @@ async def delete_app_profile(
gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
await rpc(
request,
@@ -1830,21 +2488,47 @@ async def delete_app_profile(
async def get_iam_policy(
self,
- request: Union[iam_policy_pb2.GetIamPolicyRequest, dict] = None,
+ request: Optional[Union[iam_policy_pb2.GetIamPolicyRequest, dict]] = None,
*,
- resource: str = None,
+ resource: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> policy_pb2.Policy:
r"""Gets the access control policy for an instance
resource. Returns an empty policy if an instance exists
but does not have a policy set.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+ from google.iam.v1 import iam_policy_pb2 # type: ignore
+
+ async def sample_get_iam_policy():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = iam_policy_pb2.GetIamPolicyRequest(
+ resource="resource_value",
+ )
+
+ # Make the request
+ response = await client.get_iam_policy(request=request)
+
+ # Handle the response
+ print(response)
+
Args:
- request (Union[google.iam.v1.iam_policy_pb2.GetIamPolicyRequest, dict]):
- The request object. Request message for `GetIamPolicy`
- method.
+ request (Optional[Union[google.iam.v1.iam_policy_pb2.GetIamPolicyRequest, dict]]):
+ The request object. Request message for ``GetIamPolicy`` method.
resource (:class:`str`):
REQUIRED: The resource for which the
policy is being requested. See the
@@ -1854,11 +2538,13 @@ async def get_iam_policy(
This corresponds to the ``resource`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.iam.v1.policy_pb2.Policy:
@@ -1879,88 +2565,46 @@ async def get_iam_policy(
constraints based on attributes of the request, the
resource, or both. To learn which resources support
conditions in their IAM policies, see the [IAM
- documentation](\ https://cloud.google.com/iam/help/conditions/resource-policies).
+ documentation](https://cloud.google.com/iam/help/conditions/resource-policies).
**JSON example:**
- {
- "bindings": [
- {
- "role":
- "roles/resourcemanager.organizationAdmin",
- "members": [ "user:mike@example.com",
- "group:admins@example.com",
- "domain:google.com",
- "serviceAccount:my-project-id@appspot.gserviceaccount.com"
- ]
-
- }, { "role":
- "roles/resourcemanager.organizationViewer",
- "members": [ "user:eve@example.com" ],
- "condition": { "title": "expirable access",
- "description": "Does not grant access after
- Sep 2020", "expression": "request.time <
- timestamp('2020-10-01T00:00:00.000Z')", } }
-
- ], "etag": "BwWWja0YfJA=", "version": 3
-
- }
+ :literal:`` { "bindings": [ { "role": "roles/resourcemanager.organizationAdmin", "members": [ "user:mike@example.com", "group:admins@example.com", "domain:google.com", "serviceAccount:my-project-id@appspot.gserviceaccount.com" ] }, { "role": "roles/resourcemanager.organizationViewer", "members": [ "user:eve@example.com" ], "condition": { "title": "expirable access", "description": "Does not grant access after Sep 2020", "expression": "request.time < timestamp('2020-10-01T00:00:00.000Z')", } } ], "etag": "BwWWja0YfJA=", "version": 3 }`\ \`
**YAML example:**
- bindings: - members: - user:\ mike@example.com -
- group:\ admins@example.com - domain:google.com -
- serviceAccount:\ my-project-id@appspot.gserviceaccount.com
- role: roles/resourcemanager.organizationAdmin -
- members: - user:\ eve@example.com role:
- roles/resourcemanager.organizationViewer
- condition: title: expirable access description:
- Does not grant access after Sep 2020 expression:
- request.time <
- timestamp('2020-10-01T00:00:00.000Z') etag:
- BwWWja0YfJA= version: 3
+ :literal:`` bindings: - members: - user:mike@example.com - group:admins@example.com - domain:google.com - serviceAccount:my-project-id@appspot.gserviceaccount.com role: roles/resourcemanager.organizationAdmin - members: - user:eve@example.com role: roles/resourcemanager.organizationViewer condition: title: expirable access description: Does not grant access after Sep 2020 expression: request.time < timestamp('2020-10-01T00:00:00.000Z') etag: BwWWja0YfJA= version: 3`\ \`
For a description of IAM and its features, see the
[IAM
- documentation](\ https://cloud.google.com/iam/docs/).
+ documentation](https://cloud.google.com/iam/docs/).
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([resource])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [resource]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # The request isn't a proto-plus wrapped type,
- # so it must be constructed via keyword expansion.
+ # - The request isn't a proto-plus wrapped type,
+ # so it must be constructed via keyword expansion.
if isinstance(request, dict):
request = iam_policy_pb2.GetIamPolicyRequest(**request)
elif not request:
- request = iam_policy_pb2.GetIamPolicyRequest(
- resource=resource,
- )
+ request = iam_policy_pb2.GetIamPolicyRequest(resource=resource)
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.get_iam_policy,
- default_retry=retries.Retry(
- initial=1.0,
- maximum=60.0,
- multiplier=2,
- predicate=retries.if_exception_type(
- core_exceptions.DeadlineExceeded,
- core_exceptions.ServiceUnavailable,
- ),
- deadline=60.0,
- ),
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.get_iam_policy
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -1968,6 +2612,9 @@ async def get_iam_policy(
gapic_v1.routing_header.to_grpc_metadata((("resource", request.resource),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -1981,20 +2628,46 @@ async def get_iam_policy(
async def set_iam_policy(
self,
- request: Union[iam_policy_pb2.SetIamPolicyRequest, dict] = None,
+ request: Optional[Union[iam_policy_pb2.SetIamPolicyRequest, dict]] = None,
*,
- resource: str = None,
+ resource: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> policy_pb2.Policy:
r"""Sets the access control policy on an instance
resource. Replaces any existing policy.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+ from google.iam.v1 import iam_policy_pb2 # type: ignore
+
+ async def sample_set_iam_policy():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = iam_policy_pb2.SetIamPolicyRequest(
+ resource="resource_value",
+ )
+
+ # Make the request
+ response = await client.set_iam_policy(request=request)
+
+ # Handle the response
+ print(response)
+
Args:
- request (Union[google.iam.v1.iam_policy_pb2.SetIamPolicyRequest, dict]):
- The request object. Request message for `SetIamPolicy`
- method.
+ request (Optional[Union[google.iam.v1.iam_policy_pb2.SetIamPolicyRequest, dict]]):
+ The request object. Request message for ``SetIamPolicy`` method.
resource (:class:`str`):
REQUIRED: The resource for which the
policy is being specified. See the
@@ -2004,11 +2677,13 @@ async def set_iam_policy(
This corresponds to the ``resource`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.iam.v1.policy_pb2.Policy:
@@ -2029,78 +2704,46 @@ async def set_iam_policy(
constraints based on attributes of the request, the
resource, or both. To learn which resources support
conditions in their IAM policies, see the [IAM
- documentation](\ https://cloud.google.com/iam/help/conditions/resource-policies).
+ documentation](https://cloud.google.com/iam/help/conditions/resource-policies).
**JSON example:**
- {
- "bindings": [
- {
- "role":
- "roles/resourcemanager.organizationAdmin",
- "members": [ "user:mike@example.com",
- "group:admins@example.com",
- "domain:google.com",
- "serviceAccount:my-project-id@appspot.gserviceaccount.com"
- ]
-
- }, { "role":
- "roles/resourcemanager.organizationViewer",
- "members": [ "user:eve@example.com" ],
- "condition": { "title": "expirable access",
- "description": "Does not grant access after
- Sep 2020", "expression": "request.time <
- timestamp('2020-10-01T00:00:00.000Z')", } }
-
- ], "etag": "BwWWja0YfJA=", "version": 3
-
- }
+ :literal:`` { "bindings": [ { "role": "roles/resourcemanager.organizationAdmin", "members": [ "user:mike@example.com", "group:admins@example.com", "domain:google.com", "serviceAccount:my-project-id@appspot.gserviceaccount.com" ] }, { "role": "roles/resourcemanager.organizationViewer", "members": [ "user:eve@example.com" ], "condition": { "title": "expirable access", "description": "Does not grant access after Sep 2020", "expression": "request.time < timestamp('2020-10-01T00:00:00.000Z')", } } ], "etag": "BwWWja0YfJA=", "version": 3 }`\ \`
**YAML example:**
- bindings: - members: - user:\ mike@example.com -
- group:\ admins@example.com - domain:google.com -
- serviceAccount:\ my-project-id@appspot.gserviceaccount.com
- role: roles/resourcemanager.organizationAdmin -
- members: - user:\ eve@example.com role:
- roles/resourcemanager.organizationViewer
- condition: title: expirable access description:
- Does not grant access after Sep 2020 expression:
- request.time <
- timestamp('2020-10-01T00:00:00.000Z') etag:
- BwWWja0YfJA= version: 3
+ :literal:`` bindings: - members: - user:mike@example.com - group:admins@example.com - domain:google.com - serviceAccount:my-project-id@appspot.gserviceaccount.com role: roles/resourcemanager.organizationAdmin - members: - user:eve@example.com role: roles/resourcemanager.organizationViewer condition: title: expirable access description: Does not grant access after Sep 2020 expression: request.time < timestamp('2020-10-01T00:00:00.000Z') etag: BwWWja0YfJA= version: 3`\ \`
For a description of IAM and its features, see the
[IAM
- documentation](\ https://cloud.google.com/iam/docs/).
+ documentation](https://cloud.google.com/iam/docs/).
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([resource])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [resource]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # The request isn't a proto-plus wrapped type,
- # so it must be constructed via keyword expansion.
+ # - The request isn't a proto-plus wrapped type,
+ # so it must be constructed via keyword expansion.
if isinstance(request, dict):
request = iam_policy_pb2.SetIamPolicyRequest(**request)
elif not request:
- request = iam_policy_pb2.SetIamPolicyRequest(
- resource=resource,
- )
+ request = iam_policy_pb2.SetIamPolicyRequest(resource=resource)
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.set_iam_policy,
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.set_iam_policy
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -2108,6 +2751,9 @@ async def set_iam_policy(
gapic_v1.routing_header.to_grpc_metadata((("resource", request.resource),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -2121,21 +2767,48 @@ async def set_iam_policy(
async def test_iam_permissions(
self,
- request: Union[iam_policy_pb2.TestIamPermissionsRequest, dict] = None,
+ request: Optional[Union[iam_policy_pb2.TestIamPermissionsRequest, dict]] = None,
*,
- resource: str = None,
- permissions: Sequence[str] = None,
+ resource: Optional[str] = None,
+ permissions: Optional[MutableSequence[str]] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> iam_policy_pb2.TestIamPermissionsResponse:
r"""Returns permissions that the caller has on the
specified instance resource.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+ from google.iam.v1 import iam_policy_pb2 # type: ignore
+
+ async def sample_test_iam_permissions():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = iam_policy_pb2.TestIamPermissionsRequest(
+ resource="resource_value",
+ permissions=['permissions_value1', 'permissions_value2'],
+ )
+
+ # Make the request
+ response = await client.test_iam_permissions(request=request)
+
+ # Handle the response
+ print(response)
+
Args:
- request (Union[google.iam.v1.iam_policy_pb2.TestIamPermissionsRequest, dict]):
- The request object. Request message for
- `TestIamPermissions` method.
+ request (Optional[Union[google.iam.v1.iam_policy_pb2.TestIamPermissionsRequest, dict]]):
+ The request object. Request message for ``TestIamPermissions`` method.
resource (:class:`str`):
REQUIRED: The resource for which the
policy detail is being requested. See
@@ -2145,7 +2818,7 @@ async def test_iam_permissions(
This corresponds to the ``resource`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- permissions (:class:`Sequence[str]`):
+ permissions (:class:`MutableSequence[str]`):
The set of permissions to check for the ``resource``.
Permissions with wildcards (such as '*' or 'storage.*')
are not allowed. For more information see `IAM
@@ -2154,53 +2827,45 @@ async def test_iam_permissions(
This corresponds to the ``permissions`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.iam.v1.iam_policy_pb2.TestIamPermissionsResponse:
Response message for TestIamPermissions method.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([resource, permissions])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [resource, permissions]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # The request isn't a proto-plus wrapped type,
- # so it must be constructed via keyword expansion.
+ # - The request isn't a proto-plus wrapped type,
+ # so it must be constructed via keyword expansion.
if isinstance(request, dict):
request = iam_policy_pb2.TestIamPermissionsRequest(**request)
elif not request:
request = iam_policy_pb2.TestIamPermissionsRequest(
- resource=resource,
- permissions=permissions,
+ resource=resource, permissions=permissions
)
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.test_iam_permissions,
- default_retry=retries.Retry(
- initial=1.0,
- maximum=60.0,
- multiplier=2,
- predicate=retries.if_exception_type(
- core_exceptions.DeadlineExceeded,
- core_exceptions.ServiceUnavailable,
- ),
- deadline=60.0,
- ),
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.test_iam_permissions
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -2208,6 +2873,9 @@ async def test_iam_permissions(
gapic_v1.routing_header.to_grpc_metadata((("resource", request.resource),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -2221,18 +2889,47 @@ async def test_iam_permissions(
async def list_hot_tablets(
self,
- request: Union[bigtable_instance_admin.ListHotTabletsRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_instance_admin.ListHotTabletsRequest, dict]
+ ] = None,
*,
- parent: str = None,
+ parent: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> pagers.ListHotTabletsAsyncPager:
r"""Lists hot tablets in a cluster, within the time range
provided. Hot tablets are ordered based on CPU usage.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_list_hot_tablets():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.ListHotTabletsRequest(
+ parent="parent_value",
+ )
+
+ # Make the request
+ page_result = client.list_hot_tablets(request=request)
+
+ # Handle the response
+ async for response in page_result:
+ print(response)
+
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.ListHotTabletsRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.ListHotTabletsRequest, dict]]):
The request object. Request message for
BigtableInstanceAdmin.ListHotTablets.
parent (:class:`str`):
@@ -2243,11 +2940,13 @@ async def list_hot_tablets(
This corresponds to the ``parent`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_admin_v2.services.bigtable_instance_admin.pagers.ListHotTabletsAsyncPager:
@@ -2259,16 +2958,1074 @@ async def list_hot_tablets(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([parent])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_instance_admin.ListHotTabletsRequest):
+ request = bigtable_instance_admin.ListHotTabletsRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if parent is not None:
+ request.parent = parent
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.list_hot_tablets
+ ]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
+ # Send the request.
+ response = await rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # This method is paged; wrap the response in a pager, which provides
+ # an `__aiter__` convenience method.
+ response = pagers.ListHotTabletsAsyncPager(
+ method=rpc,
+ request=request,
+ response=response,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ async def create_logical_view(
+ self,
+ request: Optional[
+ Union[bigtable_instance_admin.CreateLogicalViewRequest, dict]
+ ] = None,
+ *,
+ parent: Optional[str] = None,
+ logical_view: Optional[instance.LogicalView] = None,
+ logical_view_id: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operation_async.AsyncOperation:
+ r"""Creates a logical view within an instance.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_create_logical_view():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ logical_view = bigtable_admin_v2.LogicalView()
+ logical_view.query = "query_value"
+
+ request = bigtable_admin_v2.CreateLogicalViewRequest(
+ parent="parent_value",
+ logical_view_id="logical_view_id_value",
+ logical_view=logical_view,
+ )
+
+ # Make the request
+ operation = client.create_logical_view(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = (await operation).result()
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.CreateLogicalViewRequest, dict]]):
+ The request object. Request message for
+ BigtableInstanceAdmin.CreateLogicalView.
+ parent (:class:`str`):
+ Required. The parent instance where this logical view
+ will be created. Format:
+ ``projects/{project}/instances/{instance}``.
+
+ This corresponds to the ``parent`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ logical_view (:class:`google.cloud.bigtable_admin_v2.types.LogicalView`):
+ Required. The logical view to create.
+ This corresponds to the ``logical_view`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ logical_view_id (:class:`str`):
+ Required. The ID to use for the
+ logical view, which will become the
+ final component of the logical view's
+ resource name.
+
+ This corresponds to the ``logical_view_id`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.api_core.operation_async.AsyncOperation:
+ An object representing a long-running operation.
+
+ The result type for the operation will be
+ :class:`google.cloud.bigtable_admin_v2.types.LogicalView`
+ A SQL logical view object that can be referenced in SQL
+ queries.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent, logical_view, logical_view_id]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_instance_admin.CreateLogicalViewRequest):
+ request = bigtable_instance_admin.CreateLogicalViewRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if parent is not None:
+ request.parent = parent
+ if logical_view is not None:
+ request.logical_view = logical_view
+ if logical_view_id is not None:
+ request.logical_view_id = logical_view_id
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.create_logical_view
+ ]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
+ # Send the request.
+ response = await rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Wrap the response in an operation future.
+ response = operation_async.from_gapic(
+ response,
+ self._client._transport.operations_client,
+ instance.LogicalView,
+ metadata_type=bigtable_instance_admin.CreateLogicalViewMetadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ async def get_logical_view(
+ self,
+ request: Optional[
+ Union[bigtable_instance_admin.GetLogicalViewRequest, dict]
+ ] = None,
+ *,
+ name: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> instance.LogicalView:
+ r"""Gets information about a logical view.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_get_logical_view():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.GetLogicalViewRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ response = await client.get_logical_view(request=request)
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.GetLogicalViewRequest, dict]]):
+ The request object. Request message for
+ BigtableInstanceAdmin.GetLogicalView.
+ name (:class:`str`):
+ Required. The unique name of the requested logical view.
+ Values are of the form
+ ``projects/{project}/instances/{instance}/logicalViews/{logical_view}``.
+
+ This corresponds to the ``name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.cloud.bigtable_admin_v2.types.LogicalView:
+ A SQL logical view object that can be
+ referenced in SQL queries.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_instance_admin.GetLogicalViewRequest):
+ request = bigtable_instance_admin.GetLogicalViewRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.get_logical_view
+ ]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
+ # Send the request.
+ response = await rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ async def list_logical_views(
+ self,
+ request: Optional[
+ Union[bigtable_instance_admin.ListLogicalViewsRequest, dict]
+ ] = None,
+ *,
+ parent: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> pagers.ListLogicalViewsAsyncPager:
+ r"""Lists information about logical views in an instance.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_list_logical_views():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.ListLogicalViewsRequest(
+ parent="parent_value",
+ )
+
+ # Make the request
+ page_result = client.list_logical_views(request=request)
+
+ # Handle the response
+ async for response in page_result:
+ print(response)
+
+ Args:
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.ListLogicalViewsRequest, dict]]):
+ The request object. Request message for
+ BigtableInstanceAdmin.ListLogicalViews.
+ parent (:class:`str`):
+ Required. The unique name of the instance for which the
+ list of logical views is requested. Values are of the
+ form ``projects/{project}/instances/{instance}``.
+
+ This corresponds to the ``parent`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.cloud.bigtable_admin_v2.services.bigtable_instance_admin.pagers.ListLogicalViewsAsyncPager:
+ Response message for
+ BigtableInstanceAdmin.ListLogicalViews.
+ Iterating over this object will yield
+ results and resolve additional pages
+ automatically.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_instance_admin.ListLogicalViewsRequest):
+ request = bigtable_instance_admin.ListLogicalViewsRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if parent is not None:
+ request.parent = parent
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.list_logical_views
+ ]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
+ # Send the request.
+ response = await rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # This method is paged; wrap the response in a pager, which provides
+ # an `__aiter__` convenience method.
+ response = pagers.ListLogicalViewsAsyncPager(
+ method=rpc,
+ request=request,
+ response=response,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ async def update_logical_view(
+ self,
+ request: Optional[
+ Union[bigtable_instance_admin.UpdateLogicalViewRequest, dict]
+ ] = None,
+ *,
+ logical_view: Optional[instance.LogicalView] = None,
+ update_mask: Optional[field_mask_pb2.FieldMask] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operation_async.AsyncOperation:
+ r"""Updates a logical view within an instance.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_update_logical_view():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ logical_view = bigtable_admin_v2.LogicalView()
+ logical_view.query = "query_value"
+
+ request = bigtable_admin_v2.UpdateLogicalViewRequest(
+ logical_view=logical_view,
+ )
+
+ # Make the request
+ operation = client.update_logical_view(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = (await operation).result()
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.UpdateLogicalViewRequest, dict]]):
+ The request object. Request message for
+ BigtableInstanceAdmin.UpdateLogicalView.
+ logical_view (:class:`google.cloud.bigtable_admin_v2.types.LogicalView`):
+ Required. The logical view to update.
+
+ The logical view's ``name`` field is used to identify
+ the view to update. Format:
+ ``projects/{project}/instances/{instance}/logicalViews/{logical_view}``.
+
+ This corresponds to the ``logical_view`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`):
+ Optional. The list of fields to
+ update.
+
+ This corresponds to the ``update_mask`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.api_core.operation_async.AsyncOperation:
+ An object representing a long-running operation.
+
+ The result type for the operation will be
+ :class:`google.cloud.bigtable_admin_v2.types.LogicalView`
+ A SQL logical view object that can be referenced in SQL
+ queries.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [logical_view, update_mask]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_instance_admin.UpdateLogicalViewRequest):
+ request = bigtable_instance_admin.UpdateLogicalViewRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if logical_view is not None:
+ request.logical_view = logical_view
+ if update_mask is not None:
+ request.update_mask = update_mask
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.update_logical_view
+ ]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata(
+ (("logical_view.name", request.logical_view.name),)
+ ),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
+ # Send the request.
+ response = await rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Wrap the response in an operation future.
+ response = operation_async.from_gapic(
+ response,
+ self._client._transport.operations_client,
+ instance.LogicalView,
+ metadata_type=bigtable_instance_admin.UpdateLogicalViewMetadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ async def delete_logical_view(
+ self,
+ request: Optional[
+ Union[bigtable_instance_admin.DeleteLogicalViewRequest, dict]
+ ] = None,
+ *,
+ name: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> None:
+ r"""Deletes a logical view from an instance.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_delete_logical_view():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.DeleteLogicalViewRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ await client.delete_logical_view(request=request)
+
+ Args:
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.DeleteLogicalViewRequest, dict]]):
+ The request object. Request message for
+ BigtableInstanceAdmin.DeleteLogicalView.
+ name (:class:`str`):
+ Required. The unique name of the logical view to be
+ deleted. Format:
+ ``projects/{project}/instances/{instance}/logicalViews/{logical_view}``.
+
+ This corresponds to the ``name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_instance_admin.DeleteLogicalViewRequest):
+ request = bigtable_instance_admin.DeleteLogicalViewRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.delete_logical_view
+ ]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
+ # Send the request.
+ await rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ async def create_materialized_view(
+ self,
+ request: Optional[
+ Union[bigtable_instance_admin.CreateMaterializedViewRequest, dict]
+ ] = None,
+ *,
+ parent: Optional[str] = None,
+ materialized_view: Optional[instance.MaterializedView] = None,
+ materialized_view_id: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operation_async.AsyncOperation:
+ r"""Creates a materialized view within an instance.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_create_materialized_view():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ materialized_view = bigtable_admin_v2.MaterializedView()
+ materialized_view.query = "query_value"
+
+ request = bigtable_admin_v2.CreateMaterializedViewRequest(
+ parent="parent_value",
+ materialized_view_id="materialized_view_id_value",
+ materialized_view=materialized_view,
+ )
+
+ # Make the request
+ operation = client.create_materialized_view(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = (await operation).result()
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.CreateMaterializedViewRequest, dict]]):
+ The request object. Request message for
+ BigtableInstanceAdmin.CreateMaterializedView.
+ parent (:class:`str`):
+ Required. The parent instance where this materialized
+ view will be created. Format:
+ ``projects/{project}/instances/{instance}``.
+
+ This corresponds to the ``parent`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ materialized_view (:class:`google.cloud.bigtable_admin_v2.types.MaterializedView`):
+ Required. The materialized view to
+ create.
+
+ This corresponds to the ``materialized_view`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ materialized_view_id (:class:`str`):
+ Required. The ID to use for the
+ materialized view, which will become the
+ final component of the materialized
+ view's resource name.
+
+ This corresponds to the ``materialized_view_id`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.api_core.operation_async.AsyncOperation:
+ An object representing a long-running operation.
+
+ The result type for the operation will be
+ :class:`google.cloud.bigtable_admin_v2.types.MaterializedView`
+ A materialized view object that can be referenced in SQL
+ queries.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent, materialized_view, materialized_view_id]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(
+ request, bigtable_instance_admin.CreateMaterializedViewRequest
+ ):
+ request = bigtable_instance_admin.CreateMaterializedViewRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if parent is not None:
+ request.parent = parent
+ if materialized_view is not None:
+ request.materialized_view = materialized_view
+ if materialized_view_id is not None:
+ request.materialized_view_id = materialized_view_id
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.create_materialized_view
+ ]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
+ # Send the request.
+ response = await rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Wrap the response in an operation future.
+ response = operation_async.from_gapic(
+ response,
+ self._client._transport.operations_client,
+ instance.MaterializedView,
+ metadata_type=bigtable_instance_admin.CreateMaterializedViewMetadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ async def get_materialized_view(
+ self,
+ request: Optional[
+ Union[bigtable_instance_admin.GetMaterializedViewRequest, dict]
+ ] = None,
+ *,
+ name: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> instance.MaterializedView:
+ r"""Gets information about a materialized view.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_get_materialized_view():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.GetMaterializedViewRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ response = await client.get_materialized_view(request=request)
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.GetMaterializedViewRequest, dict]]):
+ The request object. Request message for
+ BigtableInstanceAdmin.GetMaterializedView.
+ name (:class:`str`):
+ Required. The unique name of the requested materialized
+ view. Values are of the form
+ ``projects/{project}/instances/{instance}/materializedViews/{materialized_view}``.
+
+ This corresponds to the ``name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.cloud.bigtable_admin_v2.types.MaterializedView:
+ A materialized view object that can
+ be referenced in SQL queries.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_instance_admin.GetMaterializedViewRequest):
+ request = bigtable_instance_admin.GetMaterializedViewRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.get_materialized_view
+ ]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
+ # Send the request.
+ response = await rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ async def list_materialized_views(
+ self,
+ request: Optional[
+ Union[bigtable_instance_admin.ListMaterializedViewsRequest, dict]
+ ] = None,
+ *,
+ parent: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> pagers.ListMaterializedViewsAsyncPager:
+ r"""Lists information about materialized views in an
+ instance.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_list_materialized_views():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.ListMaterializedViewsRequest(
+ parent="parent_value",
+ )
+
+ # Make the request
+ page_result = client.list_materialized_views(request=request)
+
+ # Handle the response
+ async for response in page_result:
+ print(response)
+
+ Args:
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.ListMaterializedViewsRequest, dict]]):
+ The request object. Request message for
+ BigtableInstanceAdmin.ListMaterializedViews.
+ parent (:class:`str`):
+ Required. The unique name of the instance for which the
+ list of materialized views is requested. Values are of
+ the form ``projects/{project}/instances/{instance}``.
+
+ This corresponds to the ``parent`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.cloud.bigtable_admin_v2.services.bigtable_instance_admin.pagers.ListMaterializedViewsAsyncPager:
+ Response message for
+ BigtableInstanceAdmin.ListMaterializedViews.
+ Iterating over this object will yield
+ results and resolve additional pages
+ automatically.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_instance_admin.ListHotTabletsRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(
+ request, bigtable_instance_admin.ListMaterializedViewsRequest
+ ):
+ request = bigtable_instance_admin.ListMaterializedViewsRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
@@ -2277,21 +4034,9 @@ async def list_hot_tablets(
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.list_hot_tablets,
- default_retry=retries.Retry(
- initial=1.0,
- maximum=60.0,
- multiplier=2,
- predicate=retries.if_exception_type(
- core_exceptions.DeadlineExceeded,
- core_exceptions.ServiceUnavailable,
- ),
- deadline=60.0,
- ),
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.list_materialized_views
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -2299,6 +4044,9 @@ async def list_hot_tablets(
gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -2309,31 +4057,284 @@ async def list_hot_tablets(
# This method is paged; wrap the response in a pager, which provides
# an `__aiter__` convenience method.
- response = pagers.ListHotTabletsAsyncPager(
+ response = pagers.ListMaterializedViewsAsyncPager(
method=rpc,
request=request,
response=response,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ async def update_materialized_view(
+ self,
+ request: Optional[
+ Union[bigtable_instance_admin.UpdateMaterializedViewRequest, dict]
+ ] = None,
+ *,
+ materialized_view: Optional[instance.MaterializedView] = None,
+ update_mask: Optional[field_mask_pb2.FieldMask] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operation_async.AsyncOperation:
+ r"""Updates a materialized view within an instance.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_update_materialized_view():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ materialized_view = bigtable_admin_v2.MaterializedView()
+ materialized_view.query = "query_value"
+
+ request = bigtable_admin_v2.UpdateMaterializedViewRequest(
+ materialized_view=materialized_view,
+ )
+
+ # Make the request
+ operation = client.update_materialized_view(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = (await operation).result()
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.UpdateMaterializedViewRequest, dict]]):
+ The request object. Request message for
+ BigtableInstanceAdmin.UpdateMaterializedView.
+ materialized_view (:class:`google.cloud.bigtable_admin_v2.types.MaterializedView`):
+ Required. The materialized view to update.
+
+ The materialized view's ``name`` field is used to
+ identify the view to update. Format:
+ ``projects/{project}/instances/{instance}/materializedViews/{materialized_view}``.
+
+ This corresponds to the ``materialized_view`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`):
+ Optional. The list of fields to
+ update.
+
+ This corresponds to the ``update_mask`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.api_core.operation_async.AsyncOperation:
+ An object representing a long-running operation.
+
+ The result type for the operation will be
+ :class:`google.cloud.bigtable_admin_v2.types.MaterializedView`
+ A materialized view object that can be referenced in SQL
+ queries.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [materialized_view, update_mask]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(
+ request, bigtable_instance_admin.UpdateMaterializedViewRequest
+ ):
+ request = bigtable_instance_admin.UpdateMaterializedViewRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if materialized_view is not None:
+ request.materialized_view = materialized_view
+ if update_mask is not None:
+ request.update_mask = update_mask
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.update_materialized_view
+ ]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata(
+ (("materialized_view.name", request.materialized_view.name),)
+ ),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
+ # Send the request.
+ response = await rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
metadata=metadata,
)
+ # Wrap the response in an operation future.
+ response = operation_async.from_gapic(
+ response,
+ self._client._transport.operations_client,
+ instance.MaterializedView,
+ metadata_type=bigtable_instance_admin.UpdateMaterializedViewMetadata,
+ )
+
# Done; return the response.
return response
- async def __aenter__(self):
+ async def delete_materialized_view(
+ self,
+ request: Optional[
+ Union[bigtable_instance_admin.DeleteMaterializedViewRequest, dict]
+ ] = None,
+ *,
+ name: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> None:
+ r"""Deletes a materialized view from an instance.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_delete_materialized_view():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.DeleteMaterializedViewRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ await client.delete_materialized_view(request=request)
+
+ Args:
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.DeleteMaterializedViewRequest, dict]]):
+ The request object. Request message for
+ BigtableInstanceAdmin.DeleteMaterializedView.
+ name (:class:`str`):
+ Required. The unique name of the materialized view to be
+ deleted. Format:
+ ``projects/{project}/instances/{instance}/materializedViews/{materialized_view}``.
+
+ This corresponds to the ``name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(
+ request, bigtable_instance_admin.DeleteMaterializedViewRequest
+ ):
+ request = bigtable_instance_admin.DeleteMaterializedViewRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.delete_materialized_view
+ ]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
+ # Send the request.
+ await rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ async def __aenter__(self) -> "BigtableInstanceAdminAsyncClient":
return self
async def __aexit__(self, exc_type, exc, tb):
await self.transport.close()
-try:
- DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
- gapic_version=pkg_resources.get_distribution(
- "google-cloud-bigtable-admin",
- ).version,
- )
-except pkg_resources.DistributionNotFound:
- DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
+DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
+ gapic_version=package_version.__version__
+)
+
+if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER
+ DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__
__all__ = ("BigtableInstanceAdminAsyncClient",)
diff --git a/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/client.py b/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/client.py
index fe14b82be..9d64108bb 100644
--- a/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/client.py
+++ b/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/client.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -14,10 +14,27 @@
# limitations under the License.
#
from collections import OrderedDict
+from http import HTTPStatus
+import json
+import logging as std_logging
import os
import re
-from typing import Dict, Mapping, Optional, Sequence, Tuple, Type, Union
-import pkg_resources
+from typing import (
+ Dict,
+ Callable,
+ Mapping,
+ MutableMapping,
+ MutableSequence,
+ Optional,
+ Sequence,
+ Tuple,
+ Type,
+ Union,
+ cast,
+)
+import warnings
+
+from google.cloud.bigtable_admin_v2 import gapic_version as package_version
from google.api_core import client_options as client_options_lib
from google.api_core import exceptions as core_exceptions
@@ -28,11 +45,21 @@
from google.auth.transport.grpc import SslCredentials # type: ignore
from google.auth.exceptions import MutualTLSChannelError # type: ignore
from google.oauth2 import service_account # type: ignore
+import google.protobuf
try:
- OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault]
+ OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None]
except AttributeError: # pragma: NO COVER
- OptionalRetry = Union[retries.Retry, object] # type: ignore
+ OptionalRetry = Union[retries.Retry, object, None] # type: ignore
+
+try:
+ from google.api_core import client_logging # type: ignore
+
+ CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER
+except ImportError: # pragma: NO COVER
+ CLIENT_LOGGING_SUPPORTED = False
+
+_LOGGER = std_logging.getLogger(__name__)
from google.api_core import operation # type: ignore
from google.api_core import operation_async # type: ignore
@@ -48,6 +75,7 @@
from .transports.base import BigtableInstanceAdminTransport, DEFAULT_CLIENT_INFO
from .transports.grpc import BigtableInstanceAdminGrpcTransport
from .transports.grpc_asyncio import BigtableInstanceAdminGrpcAsyncIOTransport
+from .transports.rest import BigtableInstanceAdminRestTransport
class BigtableInstanceAdminClientMeta(type):
@@ -63,10 +91,11 @@ class BigtableInstanceAdminClientMeta(type):
) # type: Dict[str, Type[BigtableInstanceAdminTransport]]
_transport_registry["grpc"] = BigtableInstanceAdminGrpcTransport
_transport_registry["grpc_asyncio"] = BigtableInstanceAdminGrpcAsyncIOTransport
+ _transport_registry["rest"] = BigtableInstanceAdminRestTransport
def get_transport_class(
cls,
- label: str = None,
+ label: Optional[str] = None,
) -> Type[BigtableInstanceAdminTransport]:
"""Returns an appropriate transport class.
@@ -123,11 +152,43 @@ def _get_default_mtls_endpoint(api_endpoint):
return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com")
+ # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead.
DEFAULT_ENDPOINT = "bigtableadmin.googleapis.com"
DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore
DEFAULT_ENDPOINT
)
+ _DEFAULT_ENDPOINT_TEMPLATE = "bigtableadmin.{UNIVERSE_DOMAIN}"
+ _DEFAULT_UNIVERSE = "googleapis.com"
+
+ @staticmethod
+ def _use_client_cert_effective():
+ """Returns whether client certificate should be used for mTLS if the
+ google-auth version supports should_use_client_cert automatic mTLS enablement.
+
+ Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var.
+
+ Returns:
+ bool: whether client certificate should be used for mTLS
+ Raises:
+ ValueError: (If using a version of google-auth without should_use_client_cert and
+ GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.)
+ """
+ # check if google-auth version supports should_use_client_cert for automatic mTLS enablement
+ if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER
+ return mtls.should_use_client_cert()
+ else: # pragma: NO COVER
+ # if unsupported, fallback to reading from env var
+ use_client_cert_str = os.getenv(
+ "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"
+ ).lower()
+ if use_client_cert_str not in ("true", "false"):
+ raise ValueError(
+ "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be"
+ " either `true` or `false`"
+ )
+ return use_client_cert_str == "true"
+
@classmethod
def from_service_account_info(cls, info: dict, *args, **kwargs):
"""Creates an instance of this client using the provided credentials
@@ -286,6 +347,50 @@ def parse_instance_path(path: str) -> Dict[str, str]:
m = re.match(r"^projects/(?P.+?)/instances/(?P.+?)$", path)
return m.groupdict() if m else {}
+ @staticmethod
+ def logical_view_path(
+ project: str,
+ instance: str,
+ logical_view: str,
+ ) -> str:
+ """Returns a fully-qualified logical_view string."""
+ return "projects/{project}/instances/{instance}/logicalViews/{logical_view}".format(
+ project=project,
+ instance=instance,
+ logical_view=logical_view,
+ )
+
+ @staticmethod
+ def parse_logical_view_path(path: str) -> Dict[str, str]:
+ """Parses a logical_view path into its component segments."""
+ m = re.match(
+ r"^projects/(?P.+?)/instances/(?P.+?)/logicalViews/(?P.+?)$",
+ path,
+ )
+ return m.groupdict() if m else {}
+
+ @staticmethod
+ def materialized_view_path(
+ project: str,
+ instance: str,
+ materialized_view: str,
+ ) -> str:
+ """Returns a fully-qualified materialized_view string."""
+ return "projects/{project}/instances/{instance}/materializedViews/{materialized_view}".format(
+ project=project,
+ instance=instance,
+ materialized_view=materialized_view,
+ )
+
+ @staticmethod
+ def parse_materialized_view_path(path: str) -> Dict[str, str]:
+ """Parses a materialized_view path into its component segments."""
+ m = re.match(
+ r"^projects/(?P.+?)/instances/(?P.+?)/materializedViews/(?P.+?)$",
+ path,
+ )
+ return m.groupdict() if m else {}
+
@staticmethod
def table_path(
project: str,
@@ -389,7 +494,7 @@ def parse_common_location_path(path: str) -> Dict[str, str]:
def get_mtls_endpoint_and_cert_source(
cls, client_options: Optional[client_options_lib.ClientOptions] = None
):
- """Return the API endpoint and client cert source for mutual TLS.
+ """Deprecated. Return the API endpoint and client cert source for mutual TLS.
The client cert source is determined in the following order:
(1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the
@@ -401,7 +506,7 @@ def get_mtls_endpoint_and_cert_source(
The API endpoint is determined in the following order:
(1) if `client_options.api_endpoint` if provided, use the provided one.
(2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the
- default mTLS endpoint; if the environment variabel is "never", use the default API
+ default mTLS endpoint; if the environment variable is "never", use the default API
endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise
use the default API endpoint.
@@ -419,14 +524,15 @@ def get_mtls_endpoint_and_cert_source(
Raises:
google.auth.exceptions.MutualTLSChannelError: If any errors happen.
"""
+
+ warnings.warn(
+ "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.",
+ DeprecationWarning,
+ )
if client_options is None:
client_options = client_options_lib.ClientOptions()
- use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")
+ use_client_cert = BigtableInstanceAdminClient._use_client_cert_effective()
use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto")
- if use_client_cert not in ("true", "false"):
- raise ValueError(
- "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
- )
if use_mtls_endpoint not in ("auto", "never", "always"):
raise MutualTLSChannelError(
"Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
@@ -434,7 +540,7 @@ def get_mtls_endpoint_and_cert_source(
# Figure out the client cert source to use.
client_cert_source = None
- if use_client_cert == "true":
+ if use_client_cert:
if client_options.client_cert_source:
client_cert_source = client_options.client_cert_source
elif mtls.has_default_client_cert_source():
@@ -452,12 +558,179 @@ def get_mtls_endpoint_and_cert_source(
return api_endpoint, client_cert_source
+ @staticmethod
+ def _read_environment_variables():
+ """Returns the environment variables used by the client.
+
+ Returns:
+ Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE,
+ GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables.
+
+ Raises:
+ ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not
+ any of ["true", "false"].
+ google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT
+ is not any of ["auto", "never", "always"].
+ """
+ use_client_cert = BigtableInstanceAdminClient._use_client_cert_effective()
+ use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower()
+ universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN")
+ if use_mtls_endpoint not in ("auto", "never", "always"):
+ raise MutualTLSChannelError(
+ "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
+ )
+ return use_client_cert, use_mtls_endpoint, universe_domain_env
+
+ @staticmethod
+ def _get_client_cert_source(provided_cert_source, use_cert_flag):
+ """Return the client cert source to be used by the client.
+
+ Args:
+ provided_cert_source (bytes): The client certificate source provided.
+ use_cert_flag (bool): A flag indicating whether to use the client certificate.
+
+ Returns:
+ bytes or None: The client cert source to be used by the client.
+ """
+ client_cert_source = None
+ if use_cert_flag:
+ if provided_cert_source:
+ client_cert_source = provided_cert_source
+ elif mtls.has_default_client_cert_source():
+ client_cert_source = mtls.default_client_cert_source()
+ return client_cert_source
+
+ @staticmethod
+ def _get_api_endpoint(
+ api_override, client_cert_source, universe_domain, use_mtls_endpoint
+ ):
+ """Return the API endpoint used by the client.
+
+ Args:
+ api_override (str): The API endpoint override. If specified, this is always
+ the return value of this function and the other arguments are not used.
+ client_cert_source (bytes): The client certificate source used by the client.
+ universe_domain (str): The universe domain used by the client.
+ use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters.
+ Possible values are "always", "auto", or "never".
+
+ Returns:
+ str: The API endpoint to be used by the client.
+ """
+ if api_override is not None:
+ api_endpoint = api_override
+ elif use_mtls_endpoint == "always" or (
+ use_mtls_endpoint == "auto" and client_cert_source
+ ):
+ _default_universe = BigtableInstanceAdminClient._DEFAULT_UNIVERSE
+ if universe_domain != _default_universe:
+ raise MutualTLSChannelError(
+ f"mTLS is not supported in any universe other than {_default_universe}."
+ )
+ api_endpoint = BigtableInstanceAdminClient.DEFAULT_MTLS_ENDPOINT
+ else:
+ api_endpoint = (
+ BigtableInstanceAdminClient._DEFAULT_ENDPOINT_TEMPLATE.format(
+ UNIVERSE_DOMAIN=universe_domain
+ )
+ )
+ return api_endpoint
+
+ @staticmethod
+ def _get_universe_domain(
+ client_universe_domain: Optional[str], universe_domain_env: Optional[str]
+ ) -> str:
+ """Return the universe domain used by the client.
+
+ Args:
+ client_universe_domain (Optional[str]): The universe domain configured via the client options.
+ universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable.
+
+ Returns:
+ str: The universe domain to be used by the client.
+
+ Raises:
+ ValueError: If the universe domain is an empty string.
+ """
+ universe_domain = BigtableInstanceAdminClient._DEFAULT_UNIVERSE
+ if client_universe_domain is not None:
+ universe_domain = client_universe_domain
+ elif universe_domain_env is not None:
+ universe_domain = universe_domain_env
+ if len(universe_domain.strip()) == 0:
+ raise ValueError("Universe Domain cannot be an empty string.")
+ return universe_domain
+
+ def _validate_universe_domain(self):
+ """Validates client's and credentials' universe domains are consistent.
+
+ Returns:
+ bool: True iff the configured universe domain is valid.
+
+ Raises:
+ ValueError: If the configured universe domain is not valid.
+ """
+
+ # NOTE (b/349488459): universe validation is disabled until further notice.
+ return True
+
+ def _add_cred_info_for_auth_errors(
+ self, error: core_exceptions.GoogleAPICallError
+ ) -> None:
+ """Adds credential info string to error details for 401/403/404 errors.
+
+ Args:
+ error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info.
+ """
+ if error.code not in [
+ HTTPStatus.UNAUTHORIZED,
+ HTTPStatus.FORBIDDEN,
+ HTTPStatus.NOT_FOUND,
+ ]:
+ return
+
+ cred = self._transport._credentials
+
+ # get_cred_info is only available in google-auth>=2.35.0
+ if not hasattr(cred, "get_cred_info"):
+ return
+
+ # ignore the type check since pypy test fails when get_cred_info
+ # is not available
+ cred_info = cred.get_cred_info() # type: ignore
+ if cred_info and hasattr(error._details, "append"):
+ error._details.append(json.dumps(cred_info))
+
+ @property
+ def api_endpoint(self):
+ """Return the API endpoint used by the client instance.
+
+ Returns:
+ str: The API endpoint used by the client instance.
+ """
+ return self._api_endpoint
+
+ @property
+ def universe_domain(self) -> str:
+ """Return the universe domain used by the client instance.
+
+ Returns:
+ str: The universe domain used by the client instance.
+ """
+ return self._universe_domain
+
def __init__(
self,
*,
credentials: Optional[ga_credentials.Credentials] = None,
- transport: Union[str, BigtableInstanceAdminTransport, None] = None,
- client_options: Optional[client_options_lib.ClientOptions] = None,
+ transport: Optional[
+ Union[
+ str,
+ BigtableInstanceAdminTransport,
+ Callable[..., BigtableInstanceAdminTransport],
+ ]
+ ] = None,
+ client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None,
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
"""Instantiates the bigtable instance admin client.
@@ -468,25 +741,37 @@ def __init__(
credentials identify the application to the service; if none
are specified, the client will attempt to ascertain the
credentials from the environment.
- transport (Union[str, BigtableInstanceAdminTransport]): The
- transport to use. If set to None, a transport is chosen
- automatically.
- client_options (google.api_core.client_options.ClientOptions): Custom options for the
- client. It won't take effect if a ``transport`` instance is provided.
- (1) The ``api_endpoint`` property can be used to override the
- default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
- environment variable can also be used to override the endpoint:
+ transport (Optional[Union[str,BigtableInstanceAdminTransport,Callable[..., BigtableInstanceAdminTransport]]]):
+ The transport to use, or a Callable that constructs and returns a new transport.
+ If a Callable is given, it will be called with the same set of initialization
+ arguments as used in the BigtableInstanceAdminTransport constructor.
+ If set to None, a transport is chosen automatically.
+ client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]):
+ Custom options for the client.
+
+ 1. The ``api_endpoint`` property can be used to override the
+ default endpoint provided by the client when ``transport`` is
+ not explicitly provided. Only if this property is not set and
+ ``transport`` was not explicitly provided, the endpoint is
+ determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment
+ variable, which have one of the following values:
"always" (always use the default mTLS endpoint), "never" (always
- use the default regular endpoint) and "auto" (auto switch to the
- default mTLS endpoint if client certificate is present, this is
- the default value). However, the ``api_endpoint`` property takes
- precedence if provided.
- (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ use the default regular endpoint) and "auto" (auto-switch to the
+ default mTLS endpoint if client certificate is present; this is
+ the default value).
+
+ 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
is "true", then the ``client_cert_source`` property can be used
- to provide client certificate for mutual TLS transport. If
+ to provide a client certificate for mTLS transport. If
not provided, the default SSL client certificate will be used if
present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
set, no client certificate will be used.
+
+ 3. The ``universe_domain`` property can be used to override the
+ default "googleapis.com" universe. Note that the ``api_endpoint``
+ property still takes precedence; and ``universe_domain`` is
+ currently not supported for mTLS.
+
client_info (google.api_core.gapic_v1.client_info.ClientInfo):
The client info used to send a user-agent string along with
API requests. If ``None``, then default info will be used.
@@ -497,16 +782,38 @@ def __init__(
google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
creation failed for any reason.
"""
- if isinstance(client_options, dict):
- client_options = client_options_lib.from_dict(client_options)
- if client_options is None:
- client_options = client_options_lib.ClientOptions()
+ self._client_options = client_options
+ if isinstance(self._client_options, dict):
+ self._client_options = client_options_lib.from_dict(self._client_options)
+ if self._client_options is None:
+ self._client_options = client_options_lib.ClientOptions()
+ self._client_options = cast(
+ client_options_lib.ClientOptions, self._client_options
+ )
+
+ universe_domain_opt = getattr(self._client_options, "universe_domain", None)
- api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source(
- client_options
+ (
+ self._use_client_cert,
+ self._use_mtls_endpoint,
+ self._universe_domain_env,
+ ) = BigtableInstanceAdminClient._read_environment_variables()
+ self._client_cert_source = BigtableInstanceAdminClient._get_client_cert_source(
+ self._client_options.client_cert_source, self._use_client_cert
)
+ self._universe_domain = BigtableInstanceAdminClient._get_universe_domain(
+ universe_domain_opt, self._universe_domain_env
+ )
+ self._api_endpoint = None # updated below, depending on `transport`
+
+ # Initialize the universe domain validation.
+ self._is_universe_domain_valid = False
- api_key_value = getattr(client_options, "api_key", None)
+ if CLIENT_LOGGING_SUPPORTED: # pragma: NO COVER
+ # Setup logging.
+ client_logging.initialize_logging()
+
+ api_key_value = getattr(self._client_options, "api_key", None)
if api_key_value and credentials:
raise ValueError(
"client_options.api_key and credentials are mutually exclusive"
@@ -515,20 +822,33 @@ def __init__(
# Save or instantiate the transport.
# Ordinarily, we provide the transport, but allowing a custom transport
# instance provides an extensibility point for unusual situations.
- if isinstance(transport, BigtableInstanceAdminTransport):
+ transport_provided = isinstance(transport, BigtableInstanceAdminTransport)
+ if transport_provided:
# transport is a BigtableInstanceAdminTransport instance.
- if credentials or client_options.credentials_file or api_key_value:
+ if credentials or self._client_options.credentials_file or api_key_value:
raise ValueError(
"When providing a transport instance, "
"provide its credentials directly."
)
- if client_options.scopes:
+ if self._client_options.scopes:
raise ValueError(
"When providing a transport instance, provide its scopes "
"directly."
)
- self._transport = transport
- else:
+ self._transport = cast(BigtableInstanceAdminTransport, transport)
+ self._api_endpoint = self._transport.host
+
+ self._api_endpoint = (
+ self._api_endpoint
+ or BigtableInstanceAdminClient._get_api_endpoint(
+ self._client_options.api_endpoint,
+ self._client_cert_source,
+ self._universe_domain,
+ self._use_mtls_endpoint,
+ )
+ )
+
+ if not transport_provided:
import google.auth._default # type: ignore
if api_key_value and hasattr(
@@ -538,29 +858,63 @@ def __init__(
api_key_value
)
- Transport = type(self).get_transport_class(transport)
- self._transport = Transport(
+ transport_init: Union[
+ Type[BigtableInstanceAdminTransport],
+ Callable[..., BigtableInstanceAdminTransport],
+ ] = (
+ BigtableInstanceAdminClient.get_transport_class(transport)
+ if isinstance(transport, str) or transport is None
+ else cast(Callable[..., BigtableInstanceAdminTransport], transport)
+ )
+ # initialize with the provided callable or the passed in class
+ self._transport = transport_init(
credentials=credentials,
- credentials_file=client_options.credentials_file,
- host=api_endpoint,
- scopes=client_options.scopes,
- client_cert_source_for_mtls=client_cert_source_func,
- quota_project_id=client_options.quota_project_id,
+ credentials_file=self._client_options.credentials_file,
+ host=self._api_endpoint,
+ scopes=self._client_options.scopes,
+ client_cert_source_for_mtls=self._client_cert_source,
+ quota_project_id=self._client_options.quota_project_id,
client_info=client_info,
always_use_jwt_access=True,
+ api_audience=self._client_options.api_audience,
)
+ if "async" not in str(self._transport):
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ std_logging.DEBUG
+ ): # pragma: NO COVER
+ _LOGGER.debug(
+ "Created client `google.bigtable.admin_v2.BigtableInstanceAdminClient`.",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "universeDomain": getattr(
+ self._transport._credentials, "universe_domain", ""
+ ),
+ "credentialsType": f"{type(self._transport._credentials).__module__}.{type(self._transport._credentials).__qualname__}",
+ "credentialsInfo": getattr(
+ self.transport._credentials, "get_cred_info", lambda: None
+ )(),
+ }
+ if hasattr(self._transport, "_credentials")
+ else {
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "credentialsType": None,
+ },
+ )
+
def create_instance(
self,
- request: Union[bigtable_instance_admin.CreateInstanceRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_instance_admin.CreateInstanceRequest, dict]
+ ] = None,
*,
- parent: str = None,
- instance_id: str = None,
- instance: gba_instance.Instance = None,
- clusters: Mapping[str, gba_instance.Cluster] = None,
+ parent: Optional[str] = None,
+ instance_id: Optional[str] = None,
+ instance: Optional[gba_instance.Instance] = None,
+ clusters: Optional[MutableMapping[str, gba_instance.Cluster]] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> operation.Operation:
r"""Create an instance within a project.
@@ -570,6 +924,41 @@ def create_instance(
scaled. If cluster_config.cluster_autoscaling_config is
non-empty, then autoscaling is enabled.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_create_instance():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ instance = bigtable_admin_v2.Instance()
+ instance.display_name = "display_name_value"
+
+ request = bigtable_admin_v2.CreateInstanceRequest(
+ parent="parent_value",
+ instance_id="instance_id_value",
+ instance=instance,
+ )
+
+ # Make the request
+ operation = client.create_instance(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = operation.result()
+
+ # Handle the response
+ print(response)
+
Args:
request (Union[google.cloud.bigtable_admin_v2.types.CreateInstanceRequest, dict]):
The request object. Request message for
@@ -597,13 +986,12 @@ def create_instance(
This corresponds to the ``instance`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- clusters (Mapping[str, google.cloud.bigtable_admin_v2.types.Cluster]):
+ clusters (MutableMapping[str, google.cloud.bigtable_admin_v2.types.Cluster]):
Required. The clusters to be created within the
instance, mapped by desired cluster ID, e.g., just
``mycluster`` rather than
``projects/myproject/instances/myinstance/clusters/mycluster``.
Fields marked ``OutputOnly`` must be left blank.
- Currently, at most four clusters can be specified.
This corresponds to the ``clusters`` field
on the ``request`` instance; if ``request`` is provided, this
@@ -611,8 +999,10 @@ def create_instance(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.api_core.operation.Operation:
@@ -626,19 +1016,20 @@ def create_instance(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([parent, instance_id, instance, clusters])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent, instance_id, instance, clusters]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_instance_admin.CreateInstanceRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
if not isinstance(request, bigtable_instance_admin.CreateInstanceRequest):
request = bigtable_instance_admin.CreateInstanceRequest(request)
# If we have keyword arguments corresponding to fields on the
@@ -662,6 +1053,9 @@ def create_instance(
gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -683,15 +1077,43 @@ def create_instance(
def get_instance(
self,
- request: Union[bigtable_instance_admin.GetInstanceRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_instance_admin.GetInstanceRequest, dict]
+ ] = None,
*,
- name: str = None,
+ name: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> instance.Instance:
r"""Gets information about an instance.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_get_instance():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.GetInstanceRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ response = client.get_instance(request=request)
+
+ # Handle the response
+ print(response)
+
Args:
request (Union[google.cloud.bigtable_admin_v2.types.GetInstanceRequest, dict]):
The request object. Request message for
@@ -707,8 +1129,10 @@ def get_instance(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_admin_v2.types.Instance:
@@ -720,19 +1144,20 @@ def get_instance(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_instance_admin.GetInstanceRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
if not isinstance(request, bigtable_instance_admin.GetInstanceRequest):
request = bigtable_instance_admin.GetInstanceRequest(request)
# If we have keyword arguments corresponding to fields on the
@@ -750,6 +1175,9 @@ def get_instance(
gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -763,15 +1191,43 @@ def get_instance(
def list_instances(
self,
- request: Union[bigtable_instance_admin.ListInstancesRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_instance_admin.ListInstancesRequest, dict]
+ ] = None,
*,
- parent: str = None,
+ parent: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> bigtable_instance_admin.ListInstancesResponse:
r"""Lists information about instances in a project.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_list_instances():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.ListInstancesRequest(
+ parent="parent_value",
+ )
+
+ # Make the request
+ response = client.list_instances(request=request)
+
+ # Handle the response
+ print(response)
+
Args:
request (Union[google.cloud.bigtable_admin_v2.types.ListInstancesRequest, dict]):
The request object. Request message for
@@ -787,8 +1243,10 @@ def list_instances(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_admin_v2.types.ListInstancesResponse:
@@ -797,19 +1255,20 @@ def list_instances(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([parent])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_instance_admin.ListInstancesRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
if not isinstance(request, bigtable_instance_admin.ListInstancesRequest):
request = bigtable_instance_admin.ListInstancesRequest(request)
# If we have keyword arguments corresponding to fields on the
@@ -827,6 +1286,9 @@ def list_instances(
gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -840,17 +1302,43 @@ def list_instances(
def update_instance(
self,
- request: Union[instance.Instance, dict] = None,
+ request: Optional[Union[instance.Instance, dict]] = None,
*,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> instance.Instance:
r"""Updates an instance within a project. This method
updates only the display name and type for an Instance.
To update other Instance properties, such as labels, use
PartialUpdateInstance.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_update_instance():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.Instance(
+ display_name="display_name_value",
+ )
+
+ # Make the request
+ response = client.update_instance(request=request)
+
+ # Handle the response
+ print(response)
+
Args:
request (Union[google.cloud.bigtable_admin_v2.types.Instance, dict]):
The request object. A collection of Bigtable
@@ -862,8 +1350,10 @@ def update_instance(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_admin_v2.types.Instance:
@@ -875,10 +1365,8 @@ def update_instance(
"""
# Create or coerce a protobuf request object.
- # Minor optimization to avoid making a copy if the user passes
- # in a instance.Instance.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
if not isinstance(request, instance.Instance):
request = instance.Instance(request)
@@ -892,6 +1380,9 @@ def update_instance(
gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -905,20 +1396,53 @@ def update_instance(
def partial_update_instance(
self,
- request: Union[
- bigtable_instance_admin.PartialUpdateInstanceRequest, dict
+ request: Optional[
+ Union[bigtable_instance_admin.PartialUpdateInstanceRequest, dict]
] = None,
*,
- instance: gba_instance.Instance = None,
- update_mask: field_mask_pb2.FieldMask = None,
+ instance: Optional[gba_instance.Instance] = None,
+ update_mask: Optional[field_mask_pb2.FieldMask] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> operation.Operation:
r"""Partially updates an instance within a project. This
method can modify all fields of an Instance and is the
preferred way to update an Instance.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_partial_update_instance():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ instance = bigtable_admin_v2.Instance()
+ instance.display_name = "display_name_value"
+
+ request = bigtable_admin_v2.PartialUpdateInstanceRequest(
+ instance=instance,
+ )
+
+ # Make the request
+ operation = client.partial_update_instance(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = operation.result()
+
+ # Handle the response
+ print(response)
+
Args:
request (Union[google.cloud.bigtable_admin_v2.types.PartialUpdateInstanceRequest, dict]):
The request object. Request message for
@@ -941,8 +1465,10 @@ def partial_update_instance(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.api_core.operation.Operation:
@@ -956,19 +1482,20 @@ def partial_update_instance(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([instance, update_mask])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [instance, update_mask]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_instance_admin.PartialUpdateInstanceRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
if not isinstance(
request, bigtable_instance_admin.PartialUpdateInstanceRequest
):
@@ -992,6 +1519,9 @@ def partial_update_instance(
),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -1013,15 +1543,40 @@ def partial_update_instance(
def delete_instance(
self,
- request: Union[bigtable_instance_admin.DeleteInstanceRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_instance_admin.DeleteInstanceRequest, dict]
+ ] = None,
*,
- name: str = None,
+ name: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> None:
r"""Delete an instance from a project.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_delete_instance():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.DeleteInstanceRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ client.delete_instance(request=request)
+
Args:
request (Union[google.cloud.bigtable_admin_v2.types.DeleteInstanceRequest, dict]):
The request object. Request message for
@@ -1037,23 +1592,26 @@ def delete_instance(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_instance_admin.DeleteInstanceRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
if not isinstance(request, bigtable_instance_admin.DeleteInstanceRequest):
request = bigtable_instance_admin.DeleteInstanceRequest(request)
# If we have keyword arguments corresponding to fields on the
@@ -1071,6 +1629,9 @@ def delete_instance(
gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
rpc(
request,
@@ -1081,14 +1642,16 @@ def delete_instance(
def create_cluster(
self,
- request: Union[bigtable_instance_admin.CreateClusterRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_instance_admin.CreateClusterRequest, dict]
+ ] = None,
*,
- parent: str = None,
- cluster_id: str = None,
- cluster: instance.Cluster = None,
+ parent: Optional[str] = None,
+ cluster_id: Optional[str] = None,
+ cluster: Optional[instance.Cluster] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> operation.Operation:
r"""Creates a cluster within an instance.
@@ -1098,6 +1661,37 @@ def create_cluster(
scaled. If cluster_config.cluster_autoscaling_config is
non-empty, then autoscaling is enabled.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_create_cluster():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.CreateClusterRequest(
+ parent="parent_value",
+ cluster_id="cluster_id_value",
+ )
+
+ # Make the request
+ operation = client.create_cluster(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = operation.result()
+
+ # Handle the response
+ print(response)
+
Args:
request (Union[google.cloud.bigtable_admin_v2.types.CreateClusterRequest, dict]):
The request object. Request message for
@@ -1129,8 +1723,10 @@ def create_cluster(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.api_core.operation.Operation:
@@ -1143,19 +1739,20 @@ def create_cluster(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([parent, cluster_id, cluster])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent, cluster_id, cluster]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_instance_admin.CreateClusterRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
if not isinstance(request, bigtable_instance_admin.CreateClusterRequest):
request = bigtable_instance_admin.CreateClusterRequest(request)
# If we have keyword arguments corresponding to fields on the
@@ -1177,6 +1774,9 @@ def create_cluster(
gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -1198,15 +1798,43 @@ def create_cluster(
def get_cluster(
self,
- request: Union[bigtable_instance_admin.GetClusterRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_instance_admin.GetClusterRequest, dict]
+ ] = None,
*,
- name: str = None,
+ name: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> instance.Cluster:
r"""Gets information about a cluster.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_get_cluster():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.GetClusterRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ response = client.get_cluster(request=request)
+
+ # Handle the response
+ print(response)
+
Args:
request (Union[google.cloud.bigtable_admin_v2.types.GetClusterRequest, dict]):
The request object. Request message for
@@ -1222,8 +1850,10 @@ def get_cluster(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_admin_v2.types.Cluster:
@@ -1234,19 +1864,20 @@ def get_cluster(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_instance_admin.GetClusterRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
if not isinstance(request, bigtable_instance_admin.GetClusterRequest):
request = bigtable_instance_admin.GetClusterRequest(request)
# If we have keyword arguments corresponding to fields on the
@@ -1264,6 +1895,9 @@ def get_cluster(
gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -1277,15 +1911,43 @@ def get_cluster(
def list_clusters(
self,
- request: Union[bigtable_instance_admin.ListClustersRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_instance_admin.ListClustersRequest, dict]
+ ] = None,
*,
- parent: str = None,
+ parent: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> bigtable_instance_admin.ListClustersResponse:
r"""Lists information about clusters in an instance.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_list_clusters():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.ListClustersRequest(
+ parent="parent_value",
+ )
+
+ # Make the request
+ response = client.list_clusters(request=request)
+
+ # Handle the response
+ print(response)
+
Args:
request (Union[google.cloud.bigtable_admin_v2.types.ListClustersRequest, dict]):
The request object. Request message for
@@ -1303,8 +1965,10 @@ def list_clusters(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_admin_v2.types.ListClustersResponse:
@@ -1313,19 +1977,20 @@ def list_clusters(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([parent])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_instance_admin.ListClustersRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
if not isinstance(request, bigtable_instance_admin.ListClustersRequest):
request = bigtable_instance_admin.ListClustersRequest(request)
# If we have keyword arguments corresponding to fields on the
@@ -1343,6 +2008,9 @@ def list_clusters(
gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -1356,11 +2024,11 @@ def list_clusters(
def update_cluster(
self,
- request: Union[instance.Cluster, dict] = None,
+ request: Optional[Union[instance.Cluster, dict]] = None,
*,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> operation.Operation:
r"""Updates a cluster within an instance.
@@ -1368,17 +2036,48 @@ def update_cluster(
cluster_config.cluster_autoscaling_config. In order to update
it, you must use PartialUpdateCluster.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_update_cluster():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.Cluster(
+ )
+
+ # Make the request
+ operation = client.update_cluster(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = operation.result()
+
+ # Handle the response
+ print(response)
+
Args:
request (Union[google.cloud.bigtable_admin_v2.types.Cluster, dict]):
- The request object. A resizable group of nodes in a
- particular cloud location, capable of serving all
+ The request object. A resizable group of nodes in a particular cloud
+ location, capable of serving all
[Tables][google.bigtable.admin.v2.Table] in the parent
[Instance][google.bigtable.admin.v2.Instance].
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.api_core.operation.Operation:
@@ -1391,10 +2090,8 @@ def update_cluster(
"""
# Create or coerce a protobuf request object.
- # Minor optimization to avoid making a copy if the user passes
- # in a instance.Cluster.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
if not isinstance(request, instance.Cluster):
request = instance.Cluster(request)
@@ -1408,6 +2105,9 @@ def update_cluster(
gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -1429,15 +2129,15 @@ def update_cluster(
def partial_update_cluster(
self,
- request: Union[
- bigtable_instance_admin.PartialUpdateClusterRequest, dict
+ request: Optional[
+ Union[bigtable_instance_admin.PartialUpdateClusterRequest, dict]
] = None,
*,
- cluster: instance.Cluster = None,
- update_mask: field_mask_pb2.FieldMask = None,
+ cluster: Optional[instance.Cluster] = None,
+ update_mask: Optional[field_mask_pb2.FieldMask] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> operation.Operation:
r"""Partially updates a cluster within a project. This method is the
preferred way to update a Cluster.
@@ -1454,6 +2154,35 @@ def partial_update_cluster(
cluster_config.cluster_autoscaling_config, and explicitly set a
serve_node count via the update_mask.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_partial_update_cluster():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.PartialUpdateClusterRequest(
+ )
+
+ # Make the request
+ operation = client.partial_update_cluster(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = operation.result()
+
+ # Handle the response
+ print(response)
+
Args:
request (Union[google.cloud.bigtable_admin_v2.types.PartialUpdateClusterRequest, dict]):
The request object. Request message for
@@ -1475,8 +2204,10 @@ def partial_update_cluster(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.api_core.operation.Operation:
@@ -1489,19 +2220,20 @@ def partial_update_cluster(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([cluster, update_mask])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [cluster, update_mask]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_instance_admin.PartialUpdateClusterRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
if not isinstance(request, bigtable_instance_admin.PartialUpdateClusterRequest):
request = bigtable_instance_admin.PartialUpdateClusterRequest(request)
# If we have keyword arguments corresponding to fields on the
@@ -1523,6 +2255,9 @@ def partial_update_cluster(
),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -1544,15 +2279,40 @@ def partial_update_cluster(
def delete_cluster(
self,
- request: Union[bigtable_instance_admin.DeleteClusterRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_instance_admin.DeleteClusterRequest, dict]
+ ] = None,
*,
- name: str = None,
+ name: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> None:
r"""Deletes a cluster from an instance.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_delete_cluster():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.DeleteClusterRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ client.delete_cluster(request=request)
+
Args:
request (Union[google.cloud.bigtable_admin_v2.types.DeleteClusterRequest, dict]):
The request object. Request message for
@@ -1568,23 +2328,26 @@ def delete_cluster(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_instance_admin.DeleteClusterRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
if not isinstance(request, bigtable_instance_admin.DeleteClusterRequest):
request = bigtable_instance_admin.DeleteClusterRequest(request)
# If we have keyword arguments corresponding to fields on the
@@ -1602,6 +2365,9 @@ def delete_cluster(
gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
rpc(
request,
@@ -1612,19 +2378,52 @@ def delete_cluster(
def create_app_profile(
self,
- request: Union[bigtable_instance_admin.CreateAppProfileRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_instance_admin.CreateAppProfileRequest, dict]
+ ] = None,
*,
- parent: str = None,
- app_profile_id: str = None,
- app_profile: instance.AppProfile = None,
+ parent: Optional[str] = None,
+ app_profile_id: Optional[str] = None,
+ app_profile: Optional[instance.AppProfile] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> instance.AppProfile:
r"""Creates an app profile within an instance.
- Args:
- request (Union[google.cloud.bigtable_admin_v2.types.CreateAppProfileRequest, dict]):
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_create_app_profile():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ app_profile = bigtable_admin_v2.AppProfile()
+ app_profile.priority = "PRIORITY_HIGH"
+
+ request = bigtable_admin_v2.CreateAppProfileRequest(
+ parent="parent_value",
+ app_profile_id="app_profile_id_value",
+ app_profile=app_profile,
+ )
+
+ # Make the request
+ response = client.create_app_profile(request=request)
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.types.CreateAppProfileRequest, dict]):
The request object. Request message for
BigtableInstanceAdmin.CreateAppProfile.
parent (str):
@@ -1654,8 +2453,10 @@ def create_app_profile(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_admin_v2.types.AppProfile:
@@ -1665,19 +2466,20 @@ def create_app_profile(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([parent, app_profile_id, app_profile])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent, app_profile_id, app_profile]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_instance_admin.CreateAppProfileRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
if not isinstance(request, bigtable_instance_admin.CreateAppProfileRequest):
request = bigtable_instance_admin.CreateAppProfileRequest(request)
# If we have keyword arguments corresponding to fields on the
@@ -1699,6 +2501,9 @@ def create_app_profile(
gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -1712,15 +2517,43 @@ def create_app_profile(
def get_app_profile(
self,
- request: Union[bigtable_instance_admin.GetAppProfileRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_instance_admin.GetAppProfileRequest, dict]
+ ] = None,
*,
- name: str = None,
+ name: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> instance.AppProfile:
r"""Gets information about an app profile.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_get_app_profile():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.GetAppProfileRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ response = client.get_app_profile(request=request)
+
+ # Handle the response
+ print(response)
+
Args:
request (Union[google.cloud.bigtable_admin_v2.types.GetAppProfileRequest, dict]):
The request object. Request message for
@@ -1736,8 +2569,10 @@ def get_app_profile(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_admin_v2.types.AppProfile:
@@ -1747,19 +2582,20 @@ def get_app_profile(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_instance_admin.GetAppProfileRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
if not isinstance(request, bigtable_instance_admin.GetAppProfileRequest):
request = bigtable_instance_admin.GetAppProfileRequest(request)
# If we have keyword arguments corresponding to fields on the
@@ -1777,6 +2613,9 @@ def get_app_profile(
gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -1790,15 +2629,44 @@ def get_app_profile(
def list_app_profiles(
self,
- request: Union[bigtable_instance_admin.ListAppProfilesRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_instance_admin.ListAppProfilesRequest, dict]
+ ] = None,
*,
- parent: str = None,
+ parent: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> pagers.ListAppProfilesPager:
r"""Lists information about app profiles in an instance.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_list_app_profiles():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.ListAppProfilesRequest(
+ parent="parent_value",
+ )
+
+ # Make the request
+ page_result = client.list_app_profiles(request=request)
+
+ # Handle the response
+ for response in page_result:
+ print(response)
+
Args:
request (Union[google.cloud.bigtable_admin_v2.types.ListAppProfilesRequest, dict]):
The request object. Request message for
@@ -1817,8 +2685,10 @@ def list_app_profiles(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_admin_v2.services.bigtable_instance_admin.pagers.ListAppProfilesPager:
@@ -1830,19 +2700,20 @@ def list_app_profiles(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([parent])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_instance_admin.ListAppProfilesRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
if not isinstance(request, bigtable_instance_admin.ListAppProfilesRequest):
request = bigtable_instance_admin.ListAppProfilesRequest(request)
# If we have keyword arguments corresponding to fields on the
@@ -1860,6 +2731,9 @@ def list_app_profiles(
gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -1874,6 +2748,8 @@ def list_app_profiles(
method=rpc,
request=request,
response=response,
+ retry=retry,
+ timeout=timeout,
metadata=metadata,
)
@@ -1882,16 +2758,51 @@ def list_app_profiles(
def update_app_profile(
self,
- request: Union[bigtable_instance_admin.UpdateAppProfileRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_instance_admin.UpdateAppProfileRequest, dict]
+ ] = None,
*,
- app_profile: instance.AppProfile = None,
- update_mask: field_mask_pb2.FieldMask = None,
+ app_profile: Optional[instance.AppProfile] = None,
+ update_mask: Optional[field_mask_pb2.FieldMask] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> operation.Operation:
r"""Updates an app profile within an instance.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_update_app_profile():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ app_profile = bigtable_admin_v2.AppProfile()
+ app_profile.priority = "PRIORITY_HIGH"
+
+ request = bigtable_admin_v2.UpdateAppProfileRequest(
+ app_profile=app_profile,
+ )
+
+ # Make the request
+ operation = client.update_app_profile(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = operation.result()
+
+ # Handle the response
+ print(response)
+
Args:
request (Union[google.cloud.bigtable_admin_v2.types.UpdateAppProfileRequest, dict]):
The request object. Request message for
@@ -1914,8 +2825,10 @@ def update_app_profile(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.api_core.operation.Operation:
@@ -1926,19 +2839,20 @@ def update_app_profile(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([app_profile, update_mask])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [app_profile, update_mask]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_instance_admin.UpdateAppProfileRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
if not isinstance(request, bigtable_instance_admin.UpdateAppProfileRequest):
request = bigtable_instance_admin.UpdateAppProfileRequest(request)
# If we have keyword arguments corresponding to fields on the
@@ -1960,6 +2874,9 @@ def update_app_profile(
),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -1981,15 +2898,42 @@ def update_app_profile(
def delete_app_profile(
self,
- request: Union[bigtable_instance_admin.DeleteAppProfileRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_instance_admin.DeleteAppProfileRequest, dict]
+ ] = None,
*,
- name: str = None,
+ name: Optional[str] = None,
+ ignore_warnings: Optional[bool] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> None:
r"""Deletes an app profile from an instance.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_delete_app_profile():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.DeleteAppProfileRequest(
+ name="name_value",
+ ignore_warnings=True,
+ )
+
+ # Make the request
+ client.delete_app_profile(request=request)
+
Args:
request (Union[google.cloud.bigtable_admin_v2.types.DeleteAppProfileRequest, dict]):
The request object. Request message for
@@ -2002,32 +2946,44 @@ def delete_app_profile(
This corresponds to the ``name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
+ ignore_warnings (bool):
+ Required. If true, ignore safety
+ checks when deleting the app profile.
+
+ This corresponds to the ``ignore_warnings`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name, ignore_warnings]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_instance_admin.DeleteAppProfileRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
if not isinstance(request, bigtable_instance_admin.DeleteAppProfileRequest):
request = bigtable_instance_admin.DeleteAppProfileRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
if name is not None:
request.name = name
+ if ignore_warnings is not None:
+ request.ignore_warnings = ignore_warnings
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
@@ -2039,6 +2995,9 @@ def delete_app_profile(
gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
rpc(
request,
@@ -2049,21 +3008,47 @@ def delete_app_profile(
def get_iam_policy(
self,
- request: Union[iam_policy_pb2.GetIamPolicyRequest, dict] = None,
+ request: Optional[Union[iam_policy_pb2.GetIamPolicyRequest, dict]] = None,
*,
- resource: str = None,
+ resource: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> policy_pb2.Policy:
r"""Gets the access control policy for an instance
resource. Returns an empty policy if an instance exists
but does not have a policy set.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+ from google.iam.v1 import iam_policy_pb2 # type: ignore
+
+ def sample_get_iam_policy():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ request = iam_policy_pb2.GetIamPolicyRequest(
+ resource="resource_value",
+ )
+
+ # Make the request
+ response = client.get_iam_policy(request=request)
+
+ # Handle the response
+ print(response)
+
Args:
request (Union[google.iam.v1.iam_policy_pb2.GetIamPolicyRequest, dict]):
- The request object. Request message for `GetIamPolicy`
- method.
+ The request object. Request message for ``GetIamPolicy`` method.
resource (str):
REQUIRED: The resource for which the
policy is being requested. See the
@@ -2076,8 +3061,10 @@ def get_iam_policy(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.iam.v1.policy_pb2.Policy:
@@ -2098,56 +3085,28 @@ def get_iam_policy(
constraints based on attributes of the request, the
resource, or both. To learn which resources support
conditions in their IAM policies, see the [IAM
- documentation](\ https://cloud.google.com/iam/help/conditions/resource-policies).
+ documentation](https://cloud.google.com/iam/help/conditions/resource-policies).
**JSON example:**
- {
- "bindings": [
- {
- "role":
- "roles/resourcemanager.organizationAdmin",
- "members": [ "user:mike@example.com",
- "group:admins@example.com",
- "domain:google.com",
- "serviceAccount:my-project-id@appspot.gserviceaccount.com"
- ]
-
- }, { "role":
- "roles/resourcemanager.organizationViewer",
- "members": [ "user:eve@example.com" ],
- "condition": { "title": "expirable access",
- "description": "Does not grant access after
- Sep 2020", "expression": "request.time <
- timestamp('2020-10-01T00:00:00.000Z')", } }
-
- ], "etag": "BwWWja0YfJA=", "version": 3
-
- }
+ :literal:`` { "bindings": [ { "role": "roles/resourcemanager.organizationAdmin", "members": [ "user:mike@example.com", "group:admins@example.com", "domain:google.com", "serviceAccount:my-project-id@appspot.gserviceaccount.com" ] }, { "role": "roles/resourcemanager.organizationViewer", "members": [ "user:eve@example.com" ], "condition": { "title": "expirable access", "description": "Does not grant access after Sep 2020", "expression": "request.time < timestamp('2020-10-01T00:00:00.000Z')", } } ], "etag": "BwWWja0YfJA=", "version": 3 }`\ \`
**YAML example:**
- bindings: - members: - user:\ mike@example.com -
- group:\ admins@example.com - domain:google.com -
- serviceAccount:\ my-project-id@appspot.gserviceaccount.com
- role: roles/resourcemanager.organizationAdmin -
- members: - user:\ eve@example.com role:
- roles/resourcemanager.organizationViewer
- condition: title: expirable access description:
- Does not grant access after Sep 2020 expression:
- request.time <
- timestamp('2020-10-01T00:00:00.000Z') etag:
- BwWWja0YfJA= version: 3
+ :literal:`` bindings: - members: - user:mike@example.com - group:admins@example.com - domain:google.com - serviceAccount:my-project-id@appspot.gserviceaccount.com role: roles/resourcemanager.organizationAdmin - members: - user:eve@example.com role: roles/resourcemanager.organizationViewer condition: title: expirable access description: Does not grant access after Sep 2020 expression: request.time < timestamp('2020-10-01T00:00:00.000Z') etag: BwWWja0YfJA= version: 3`\ \`
For a description of IAM and its features, see the
[IAM
- documentation](\ https://cloud.google.com/iam/docs/).
+ documentation](https://cloud.google.com/iam/docs/).
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([resource])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [resource]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
@@ -2155,8 +3114,8 @@ def get_iam_policy(
)
if isinstance(request, dict):
- # The request isn't a proto-plus wrapped type,
- # so it must be constructed via keyword expansion.
+ # - The request isn't a proto-plus wrapped type,
+ # so it must be constructed via keyword expansion.
request = iam_policy_pb2.GetIamPolicyRequest(**request)
elif not request:
# Null request, just make one.
@@ -2174,6 +3133,9 @@ def get_iam_policy(
gapic_v1.routing_header.to_grpc_metadata((("resource", request.resource),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -2187,20 +3149,46 @@ def get_iam_policy(
def set_iam_policy(
self,
- request: Union[iam_policy_pb2.SetIamPolicyRequest, dict] = None,
+ request: Optional[Union[iam_policy_pb2.SetIamPolicyRequest, dict]] = None,
*,
- resource: str = None,
+ resource: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> policy_pb2.Policy:
r"""Sets the access control policy on an instance
resource. Replaces any existing policy.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+ from google.iam.v1 import iam_policy_pb2 # type: ignore
+
+ def sample_set_iam_policy():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ request = iam_policy_pb2.SetIamPolicyRequest(
+ resource="resource_value",
+ )
+
+ # Make the request
+ response = client.set_iam_policy(request=request)
+
+ # Handle the response
+ print(response)
+
Args:
request (Union[google.iam.v1.iam_policy_pb2.SetIamPolicyRequest, dict]):
- The request object. Request message for `SetIamPolicy`
- method.
+ The request object. Request message for ``SetIamPolicy`` method.
resource (str):
REQUIRED: The resource for which the
policy is being specified. See the
@@ -2213,8 +3201,10 @@ def set_iam_policy(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.iam.v1.policy_pb2.Policy:
@@ -2235,56 +3225,28 @@ def set_iam_policy(
constraints based on attributes of the request, the
resource, or both. To learn which resources support
conditions in their IAM policies, see the [IAM
- documentation](\ https://cloud.google.com/iam/help/conditions/resource-policies).
+ documentation](https://cloud.google.com/iam/help/conditions/resource-policies).
**JSON example:**
- {
- "bindings": [
- {
- "role":
- "roles/resourcemanager.organizationAdmin",
- "members": [ "user:mike@example.com",
- "group:admins@example.com",
- "domain:google.com",
- "serviceAccount:my-project-id@appspot.gserviceaccount.com"
- ]
-
- }, { "role":
- "roles/resourcemanager.organizationViewer",
- "members": [ "user:eve@example.com" ],
- "condition": { "title": "expirable access",
- "description": "Does not grant access after
- Sep 2020", "expression": "request.time <
- timestamp('2020-10-01T00:00:00.000Z')", } }
-
- ], "etag": "BwWWja0YfJA=", "version": 3
-
- }
+ :literal:`` { "bindings": [ { "role": "roles/resourcemanager.organizationAdmin", "members": [ "user:mike@example.com", "group:admins@example.com", "domain:google.com", "serviceAccount:my-project-id@appspot.gserviceaccount.com" ] }, { "role": "roles/resourcemanager.organizationViewer", "members": [ "user:eve@example.com" ], "condition": { "title": "expirable access", "description": "Does not grant access after Sep 2020", "expression": "request.time < timestamp('2020-10-01T00:00:00.000Z')", } } ], "etag": "BwWWja0YfJA=", "version": 3 }`\ \`
**YAML example:**
- bindings: - members: - user:\ mike@example.com -
- group:\ admins@example.com - domain:google.com -
- serviceAccount:\ my-project-id@appspot.gserviceaccount.com
- role: roles/resourcemanager.organizationAdmin -
- members: - user:\ eve@example.com role:
- roles/resourcemanager.organizationViewer
- condition: title: expirable access description:
- Does not grant access after Sep 2020 expression:
- request.time <
- timestamp('2020-10-01T00:00:00.000Z') etag:
- BwWWja0YfJA= version: 3
+ :literal:`` bindings: - members: - user:mike@example.com - group:admins@example.com - domain:google.com - serviceAccount:my-project-id@appspot.gserviceaccount.com role: roles/resourcemanager.organizationAdmin - members: - user:eve@example.com role: roles/resourcemanager.organizationViewer condition: title: expirable access description: Does not grant access after Sep 2020 expression: request.time < timestamp('2020-10-01T00:00:00.000Z') etag: BwWWja0YfJA= version: 3`\ \`
For a description of IAM and its features, see the
[IAM
- documentation](\ https://cloud.google.com/iam/docs/).
+ documentation](https://cloud.google.com/iam/docs/).
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([resource])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [resource]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
@@ -2292,8 +3254,8 @@ def set_iam_policy(
)
if isinstance(request, dict):
- # The request isn't a proto-plus wrapped type,
- # so it must be constructed via keyword expansion.
+ # - The request isn't a proto-plus wrapped type,
+ # so it must be constructed via keyword expansion.
request = iam_policy_pb2.SetIamPolicyRequest(**request)
elif not request:
# Null request, just make one.
@@ -2311,6 +3273,9 @@ def set_iam_policy(
gapic_v1.routing_header.to_grpc_metadata((("resource", request.resource),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -2324,21 +3289,48 @@ def set_iam_policy(
def test_iam_permissions(
self,
- request: Union[iam_policy_pb2.TestIamPermissionsRequest, dict] = None,
+ request: Optional[Union[iam_policy_pb2.TestIamPermissionsRequest, dict]] = None,
*,
- resource: str = None,
- permissions: Sequence[str] = None,
+ resource: Optional[str] = None,
+ permissions: Optional[MutableSequence[str]] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> iam_policy_pb2.TestIamPermissionsResponse:
r"""Returns permissions that the caller has on the
specified instance resource.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+ from google.iam.v1 import iam_policy_pb2 # type: ignore
+
+ def sample_test_iam_permissions():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ request = iam_policy_pb2.TestIamPermissionsRequest(
+ resource="resource_value",
+ permissions=['permissions_value1', 'permissions_value2'],
+ )
+
+ # Make the request
+ response = client.test_iam_permissions(request=request)
+
+ # Handle the response
+ print(response)
+
Args:
request (Union[google.iam.v1.iam_policy_pb2.TestIamPermissionsRequest, dict]):
- The request object. Request message for
- `TestIamPermissions` method.
+ The request object. Request message for ``TestIamPermissions`` method.
resource (str):
REQUIRED: The resource for which the
policy detail is being requested. See
@@ -2348,7 +3340,7 @@ def test_iam_permissions(
This corresponds to the ``resource`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- permissions (Sequence[str]):
+ permissions (MutableSequence[str]):
The set of permissions to check for the ``resource``.
Permissions with wildcards (such as '*' or 'storage.*')
are not allowed. For more information see `IAM
@@ -2360,17 +3352,22 @@ def test_iam_permissions(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.iam.v1.iam_policy_pb2.TestIamPermissionsResponse:
Response message for TestIamPermissions method.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([resource, permissions])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [resource, permissions]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
@@ -2378,8 +3375,8 @@ def test_iam_permissions(
)
if isinstance(request, dict):
- # The request isn't a proto-plus wrapped type,
- # so it must be constructed via keyword expansion.
+ # - The request isn't a proto-plus wrapped type,
+ # so it must be constructed via keyword expansion.
request = iam_policy_pb2.TestIamPermissionsRequest(**request)
elif not request:
# Null request, just make one.
@@ -2399,6 +3396,9 @@ def test_iam_permissions(
gapic_v1.routing_header.to_grpc_metadata((("resource", request.resource),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -2412,16 +3412,45 @@ def test_iam_permissions(
def list_hot_tablets(
self,
- request: Union[bigtable_instance_admin.ListHotTabletsRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_instance_admin.ListHotTabletsRequest, dict]
+ ] = None,
*,
- parent: str = None,
+ parent: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> pagers.ListHotTabletsPager:
r"""Lists hot tablets in a cluster, within the time range
provided. Hot tablets are ordered based on CPU usage.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_list_hot_tablets():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.ListHotTabletsRequest(
+ parent="parent_value",
+ )
+
+ # Make the request
+ page_result = client.list_hot_tablets(request=request)
+
+ # Handle the response
+ for response in page_result:
+ print(response)
+
Args:
request (Union[google.cloud.bigtable_admin_v2.types.ListHotTabletsRequest, dict]):
The request object. Request message for
@@ -2437,8 +3466,10 @@ def list_hot_tablets(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_admin_v2.services.bigtable_instance_admin.pagers.ListHotTabletsPager:
@@ -2450,19 +3481,20 @@ def list_hot_tablets(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([parent])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_instance_admin.ListHotTabletsRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
if not isinstance(request, bigtable_instance_admin.ListHotTabletsRequest):
request = bigtable_instance_admin.ListHotTabletsRequest(request)
# If we have keyword arguments corresponding to fields on the
@@ -2480,6 +3512,9 @@ def list_hot_tablets(
gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -2494,34 +3529,1308 @@ def list_hot_tablets(
method=rpc,
request=request,
response=response,
+ retry=retry,
+ timeout=timeout,
metadata=metadata,
)
# Done; return the response.
return response
- def __enter__(self):
- return self
+ def create_logical_view(
+ self,
+ request: Optional[
+ Union[bigtable_instance_admin.CreateLogicalViewRequest, dict]
+ ] = None,
+ *,
+ parent: Optional[str] = None,
+ logical_view: Optional[instance.LogicalView] = None,
+ logical_view_id: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operation.Operation:
+ r"""Creates a logical view within an instance.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_create_logical_view():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ logical_view = bigtable_admin_v2.LogicalView()
+ logical_view.query = "query_value"
+
+ request = bigtable_admin_v2.CreateLogicalViewRequest(
+ parent="parent_value",
+ logical_view_id="logical_view_id_value",
+ logical_view=logical_view,
+ )
- def __exit__(self, type, value, traceback):
- """Releases underlying transport's resources.
+ # Make the request
+ operation = client.create_logical_view(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = operation.result()
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.types.CreateLogicalViewRequest, dict]):
+ The request object. Request message for
+ BigtableInstanceAdmin.CreateLogicalView.
+ parent (str):
+ Required. The parent instance where this logical view
+ will be created. Format:
+ ``projects/{project}/instances/{instance}``.
+
+ This corresponds to the ``parent`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ logical_view (google.cloud.bigtable_admin_v2.types.LogicalView):
+ Required. The logical view to create.
+ This corresponds to the ``logical_view`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ logical_view_id (str):
+ Required. The ID to use for the
+ logical view, which will become the
+ final component of the logical view's
+ resource name.
+
+ This corresponds to the ``logical_view_id`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.api_core.operation.Operation:
+ An object representing a long-running operation.
+
+ The result type for the operation will be
+ :class:`google.cloud.bigtable_admin_v2.types.LogicalView`
+ A SQL logical view object that can be referenced in SQL
+ queries.
- .. warning::
- ONLY use as a context manager if the transport is NOT shared
- with other clients! Exiting the with block will CLOSE the transport
- and may cause errors in other clients!
"""
- self.transport.close()
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent, logical_view, logical_view_id]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_instance_admin.CreateLogicalViewRequest):
+ request = bigtable_instance_admin.CreateLogicalViewRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if parent is not None:
+ request.parent = parent
+ if logical_view is not None:
+ request.logical_view = logical_view
+ if logical_view_id is not None:
+ request.logical_view_id = logical_view_id
-try:
- DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
- gapic_version=pkg_resources.get_distribution(
- "google-cloud-bigtable-admin",
- ).version,
- )
-except pkg_resources.DistributionNotFound:
- DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.create_logical_view]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
+ # Send the request.
+ response = rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Wrap the response in an operation future.
+ response = operation.from_gapic(
+ response,
+ self._transport.operations_client,
+ instance.LogicalView,
+ metadata_type=bigtable_instance_admin.CreateLogicalViewMetadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def get_logical_view(
+ self,
+ request: Optional[
+ Union[bigtable_instance_admin.GetLogicalViewRequest, dict]
+ ] = None,
+ *,
+ name: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> instance.LogicalView:
+ r"""Gets information about a logical view.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_get_logical_view():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.GetLogicalViewRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ response = client.get_logical_view(request=request)
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.types.GetLogicalViewRequest, dict]):
+ The request object. Request message for
+ BigtableInstanceAdmin.GetLogicalView.
+ name (str):
+ Required. The unique name of the requested logical view.
+ Values are of the form
+ ``projects/{project}/instances/{instance}/logicalViews/{logical_view}``.
+
+ This corresponds to the ``name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.cloud.bigtable_admin_v2.types.LogicalView:
+ A SQL logical view object that can be
+ referenced in SQL queries.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_instance_admin.GetLogicalViewRequest):
+ request = bigtable_instance_admin.GetLogicalViewRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.get_logical_view]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
+ # Send the request.
+ response = rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def list_logical_views(
+ self,
+ request: Optional[
+ Union[bigtable_instance_admin.ListLogicalViewsRequest, dict]
+ ] = None,
+ *,
+ parent: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> pagers.ListLogicalViewsPager:
+ r"""Lists information about logical views in an instance.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_list_logical_views():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.ListLogicalViewsRequest(
+ parent="parent_value",
+ )
+
+ # Make the request
+ page_result = client.list_logical_views(request=request)
+
+ # Handle the response
+ for response in page_result:
+ print(response)
+
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.types.ListLogicalViewsRequest, dict]):
+ The request object. Request message for
+ BigtableInstanceAdmin.ListLogicalViews.
+ parent (str):
+ Required. The unique name of the instance for which the
+ list of logical views is requested. Values are of the
+ form ``projects/{project}/instances/{instance}``.
+
+ This corresponds to the ``parent`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.cloud.bigtable_admin_v2.services.bigtable_instance_admin.pagers.ListLogicalViewsPager:
+ Response message for
+ BigtableInstanceAdmin.ListLogicalViews.
+ Iterating over this object will yield
+ results and resolve additional pages
+ automatically.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_instance_admin.ListLogicalViewsRequest):
+ request = bigtable_instance_admin.ListLogicalViewsRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if parent is not None:
+ request.parent = parent
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.list_logical_views]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
+ # Send the request.
+ response = rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # This method is paged; wrap the response in a pager, which provides
+ # an `__iter__` convenience method.
+ response = pagers.ListLogicalViewsPager(
+ method=rpc,
+ request=request,
+ response=response,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def update_logical_view(
+ self,
+ request: Optional[
+ Union[bigtable_instance_admin.UpdateLogicalViewRequest, dict]
+ ] = None,
+ *,
+ logical_view: Optional[instance.LogicalView] = None,
+ update_mask: Optional[field_mask_pb2.FieldMask] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operation.Operation:
+ r"""Updates a logical view within an instance.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_update_logical_view():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ logical_view = bigtable_admin_v2.LogicalView()
+ logical_view.query = "query_value"
+
+ request = bigtable_admin_v2.UpdateLogicalViewRequest(
+ logical_view=logical_view,
+ )
+
+ # Make the request
+ operation = client.update_logical_view(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = operation.result()
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.types.UpdateLogicalViewRequest, dict]):
+ The request object. Request message for
+ BigtableInstanceAdmin.UpdateLogicalView.
+ logical_view (google.cloud.bigtable_admin_v2.types.LogicalView):
+ Required. The logical view to update.
+
+ The logical view's ``name`` field is used to identify
+ the view to update. Format:
+ ``projects/{project}/instances/{instance}/logicalViews/{logical_view}``.
+
+ This corresponds to the ``logical_view`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ update_mask (google.protobuf.field_mask_pb2.FieldMask):
+ Optional. The list of fields to
+ update.
+
+ This corresponds to the ``update_mask`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.api_core.operation.Operation:
+ An object representing a long-running operation.
+
+ The result type for the operation will be
+ :class:`google.cloud.bigtable_admin_v2.types.LogicalView`
+ A SQL logical view object that can be referenced in SQL
+ queries.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [logical_view, update_mask]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_instance_admin.UpdateLogicalViewRequest):
+ request = bigtable_instance_admin.UpdateLogicalViewRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if logical_view is not None:
+ request.logical_view = logical_view
+ if update_mask is not None:
+ request.update_mask = update_mask
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.update_logical_view]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata(
+ (("logical_view.name", request.logical_view.name),)
+ ),
+ )
+
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
+ # Send the request.
+ response = rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Wrap the response in an operation future.
+ response = operation.from_gapic(
+ response,
+ self._transport.operations_client,
+ instance.LogicalView,
+ metadata_type=bigtable_instance_admin.UpdateLogicalViewMetadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def delete_logical_view(
+ self,
+ request: Optional[
+ Union[bigtable_instance_admin.DeleteLogicalViewRequest, dict]
+ ] = None,
+ *,
+ name: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> None:
+ r"""Deletes a logical view from an instance.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_delete_logical_view():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.DeleteLogicalViewRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ client.delete_logical_view(request=request)
+
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.types.DeleteLogicalViewRequest, dict]):
+ The request object. Request message for
+ BigtableInstanceAdmin.DeleteLogicalView.
+ name (str):
+ Required. The unique name of the logical view to be
+ deleted. Format:
+ ``projects/{project}/instances/{instance}/logicalViews/{logical_view}``.
+
+ This corresponds to the ``name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_instance_admin.DeleteLogicalViewRequest):
+ request = bigtable_instance_admin.DeleteLogicalViewRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.delete_logical_view]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
+ # Send the request.
+ rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ def create_materialized_view(
+ self,
+ request: Optional[
+ Union[bigtable_instance_admin.CreateMaterializedViewRequest, dict]
+ ] = None,
+ *,
+ parent: Optional[str] = None,
+ materialized_view: Optional[instance.MaterializedView] = None,
+ materialized_view_id: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operation.Operation:
+ r"""Creates a materialized view within an instance.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_create_materialized_view():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ materialized_view = bigtable_admin_v2.MaterializedView()
+ materialized_view.query = "query_value"
+
+ request = bigtable_admin_v2.CreateMaterializedViewRequest(
+ parent="parent_value",
+ materialized_view_id="materialized_view_id_value",
+ materialized_view=materialized_view,
+ )
+
+ # Make the request
+ operation = client.create_materialized_view(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = operation.result()
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.types.CreateMaterializedViewRequest, dict]):
+ The request object. Request message for
+ BigtableInstanceAdmin.CreateMaterializedView.
+ parent (str):
+ Required. The parent instance where this materialized
+ view will be created. Format:
+ ``projects/{project}/instances/{instance}``.
+
+ This corresponds to the ``parent`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ materialized_view (google.cloud.bigtable_admin_v2.types.MaterializedView):
+ Required. The materialized view to
+ create.
+
+ This corresponds to the ``materialized_view`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ materialized_view_id (str):
+ Required. The ID to use for the
+ materialized view, which will become the
+ final component of the materialized
+ view's resource name.
+
+ This corresponds to the ``materialized_view_id`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.api_core.operation.Operation:
+ An object representing a long-running operation.
+
+ The result type for the operation will be
+ :class:`google.cloud.bigtable_admin_v2.types.MaterializedView`
+ A materialized view object that can be referenced in SQL
+ queries.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent, materialized_view, materialized_view_id]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(
+ request, bigtable_instance_admin.CreateMaterializedViewRequest
+ ):
+ request = bigtable_instance_admin.CreateMaterializedViewRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if parent is not None:
+ request.parent = parent
+ if materialized_view is not None:
+ request.materialized_view = materialized_view
+ if materialized_view_id is not None:
+ request.materialized_view_id = materialized_view_id
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.create_materialized_view]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
+ # Send the request.
+ response = rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Wrap the response in an operation future.
+ response = operation.from_gapic(
+ response,
+ self._transport.operations_client,
+ instance.MaterializedView,
+ metadata_type=bigtable_instance_admin.CreateMaterializedViewMetadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def get_materialized_view(
+ self,
+ request: Optional[
+ Union[bigtable_instance_admin.GetMaterializedViewRequest, dict]
+ ] = None,
+ *,
+ name: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> instance.MaterializedView:
+ r"""Gets information about a materialized view.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_get_materialized_view():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.GetMaterializedViewRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ response = client.get_materialized_view(request=request)
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.types.GetMaterializedViewRequest, dict]):
+ The request object. Request message for
+ BigtableInstanceAdmin.GetMaterializedView.
+ name (str):
+ Required. The unique name of the requested materialized
+ view. Values are of the form
+ ``projects/{project}/instances/{instance}/materializedViews/{materialized_view}``.
+
+ This corresponds to the ``name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.cloud.bigtable_admin_v2.types.MaterializedView:
+ A materialized view object that can
+ be referenced in SQL queries.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_instance_admin.GetMaterializedViewRequest):
+ request = bigtable_instance_admin.GetMaterializedViewRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.get_materialized_view]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
+ # Send the request.
+ response = rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def list_materialized_views(
+ self,
+ request: Optional[
+ Union[bigtable_instance_admin.ListMaterializedViewsRequest, dict]
+ ] = None,
+ *,
+ parent: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> pagers.ListMaterializedViewsPager:
+ r"""Lists information about materialized views in an
+ instance.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_list_materialized_views():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.ListMaterializedViewsRequest(
+ parent="parent_value",
+ )
+
+ # Make the request
+ page_result = client.list_materialized_views(request=request)
+
+ # Handle the response
+ for response in page_result:
+ print(response)
+
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.types.ListMaterializedViewsRequest, dict]):
+ The request object. Request message for
+ BigtableInstanceAdmin.ListMaterializedViews.
+ parent (str):
+ Required. The unique name of the instance for which the
+ list of materialized views is requested. Values are of
+ the form ``projects/{project}/instances/{instance}``.
+
+ This corresponds to the ``parent`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.cloud.bigtable_admin_v2.services.bigtable_instance_admin.pagers.ListMaterializedViewsPager:
+ Response message for
+ BigtableInstanceAdmin.ListMaterializedViews.
+ Iterating over this object will yield
+ results and resolve additional pages
+ automatically.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(
+ request, bigtable_instance_admin.ListMaterializedViewsRequest
+ ):
+ request = bigtable_instance_admin.ListMaterializedViewsRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if parent is not None:
+ request.parent = parent
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.list_materialized_views]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
+ # Send the request.
+ response = rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # This method is paged; wrap the response in a pager, which provides
+ # an `__iter__` convenience method.
+ response = pagers.ListMaterializedViewsPager(
+ method=rpc,
+ request=request,
+ response=response,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def update_materialized_view(
+ self,
+ request: Optional[
+ Union[bigtable_instance_admin.UpdateMaterializedViewRequest, dict]
+ ] = None,
+ *,
+ materialized_view: Optional[instance.MaterializedView] = None,
+ update_mask: Optional[field_mask_pb2.FieldMask] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operation.Operation:
+ r"""Updates a materialized view within an instance.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_update_materialized_view():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ materialized_view = bigtable_admin_v2.MaterializedView()
+ materialized_view.query = "query_value"
+
+ request = bigtable_admin_v2.UpdateMaterializedViewRequest(
+ materialized_view=materialized_view,
+ )
+
+ # Make the request
+ operation = client.update_materialized_view(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = operation.result()
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.types.UpdateMaterializedViewRequest, dict]):
+ The request object. Request message for
+ BigtableInstanceAdmin.UpdateMaterializedView.
+ materialized_view (google.cloud.bigtable_admin_v2.types.MaterializedView):
+ Required. The materialized view to update.
+
+ The materialized view's ``name`` field is used to
+ identify the view to update. Format:
+ ``projects/{project}/instances/{instance}/materializedViews/{materialized_view}``.
+
+ This corresponds to the ``materialized_view`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ update_mask (google.protobuf.field_mask_pb2.FieldMask):
+ Optional. The list of fields to
+ update.
+
+ This corresponds to the ``update_mask`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.api_core.operation.Operation:
+ An object representing a long-running operation.
+
+ The result type for the operation will be
+ :class:`google.cloud.bigtable_admin_v2.types.MaterializedView`
+ A materialized view object that can be referenced in SQL
+ queries.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [materialized_view, update_mask]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(
+ request, bigtable_instance_admin.UpdateMaterializedViewRequest
+ ):
+ request = bigtable_instance_admin.UpdateMaterializedViewRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if materialized_view is not None:
+ request.materialized_view = materialized_view
+ if update_mask is not None:
+ request.update_mask = update_mask
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.update_materialized_view]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata(
+ (("materialized_view.name", request.materialized_view.name),)
+ ),
+ )
+
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
+ # Send the request.
+ response = rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Wrap the response in an operation future.
+ response = operation.from_gapic(
+ response,
+ self._transport.operations_client,
+ instance.MaterializedView,
+ metadata_type=bigtable_instance_admin.UpdateMaterializedViewMetadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def delete_materialized_view(
+ self,
+ request: Optional[
+ Union[bigtable_instance_admin.DeleteMaterializedViewRequest, dict]
+ ] = None,
+ *,
+ name: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> None:
+ r"""Deletes a materialized view from an instance.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_delete_materialized_view():
+ # Create a client
+ client = bigtable_admin_v2.BigtableInstanceAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.DeleteMaterializedViewRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ client.delete_materialized_view(request=request)
+
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.types.DeleteMaterializedViewRequest, dict]):
+ The request object. Request message for
+ BigtableInstanceAdmin.DeleteMaterializedView.
+ name (str):
+ Required. The unique name of the materialized view to be
+ deleted. Format:
+ ``projects/{project}/instances/{instance}/materializedViews/{materialized_view}``.
+
+ This corresponds to the ``name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(
+ request, bigtable_instance_admin.DeleteMaterializedViewRequest
+ ):
+ request = bigtable_instance_admin.DeleteMaterializedViewRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.delete_materialized_view]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
+ # Send the request.
+ rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ def __enter__(self) -> "BigtableInstanceAdminClient":
+ return self
+
+ def __exit__(self, type, value, traceback):
+ """Releases underlying transport's resources.
+
+ .. warning::
+ ONLY use as a context manager if the transport is NOT shared
+ with other clients! Exiting the with block will CLOSE the transport
+ and may cause errors in other clients!
+ """
+ self.transport.close()
+
+
+DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
+ gapic_version=package_version.__version__
+)
+if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER
+ DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__
__all__ = ("BigtableInstanceAdminClient",)
diff --git a/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/pagers.py b/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/pagers.py
index bfcbbf23d..ce5b67b27 100644
--- a/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/pagers.py
+++ b/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/pagers.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -13,6 +13,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+from google.api_core import gapic_v1
+from google.api_core import retry as retries
+from google.api_core import retry_async as retries_async
from typing import (
Any,
AsyncIterator,
@@ -22,8 +25,18 @@
Tuple,
Optional,
Iterator,
+ Union,
)
+try:
+ OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None]
+ OptionalAsyncRetry = Union[
+ retries_async.AsyncRetry, gapic_v1.method._MethodDefault, None
+ ]
+except AttributeError: # pragma: NO COVER
+ OptionalRetry = Union[retries.Retry, object, None] # type: ignore
+ OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore
+
from google.cloud.bigtable_admin_v2.types import bigtable_instance_admin
from google.cloud.bigtable_admin_v2.types import instance
@@ -52,7 +65,9 @@ def __init__(
request: bigtable_instance_admin.ListAppProfilesRequest,
response: bigtable_instance_admin.ListAppProfilesResponse,
*,
- metadata: Sequence[Tuple[str, str]] = ()
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
):
"""Instantiate the pager.
@@ -63,12 +78,19 @@ def __init__(
The initial request object.
response (google.cloud.bigtable_admin_v2.types.ListAppProfilesResponse):
The initial response object.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ retry (google.api_core.retry.Retry): Designation of what errors,
+ if any, should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
"""
self._method = method
self._request = bigtable_instance_admin.ListAppProfilesRequest(request)
self._response = response
+ self._retry = retry
+ self._timeout = timeout
self._metadata = metadata
def __getattr__(self, name: str) -> Any:
@@ -79,7 +101,12 @@ def pages(self) -> Iterator[bigtable_instance_admin.ListAppProfilesResponse]:
yield self._response
while self._response.next_page_token:
self._request.page_token = self._response.next_page_token
- self._response = self._method(self._request, metadata=self._metadata)
+ self._response = self._method(
+ self._request,
+ retry=self._retry,
+ timeout=self._timeout,
+ metadata=self._metadata,
+ )
yield self._response
def __iter__(self) -> Iterator[instance.AppProfile]:
@@ -116,7 +143,9 @@ def __init__(
request: bigtable_instance_admin.ListAppProfilesRequest,
response: bigtable_instance_admin.ListAppProfilesResponse,
*,
- metadata: Sequence[Tuple[str, str]] = ()
+ retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
):
"""Instantiates the pager.
@@ -127,12 +156,19 @@ def __init__(
The initial request object.
response (google.cloud.bigtable_admin_v2.types.ListAppProfilesResponse):
The initial response object.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ retry (google.api_core.retry.AsyncRetry): Designation of what errors,
+ if any, should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
"""
self._method = method
self._request = bigtable_instance_admin.ListAppProfilesRequest(request)
self._response = response
+ self._retry = retry
+ self._timeout = timeout
self._metadata = metadata
def __getattr__(self, name: str) -> Any:
@@ -145,7 +181,12 @@ async def pages(
yield self._response
while self._response.next_page_token:
self._request.page_token = self._response.next_page_token
- self._response = await self._method(self._request, metadata=self._metadata)
+ self._response = await self._method(
+ self._request,
+ retry=self._retry,
+ timeout=self._timeout,
+ metadata=self._metadata,
+ )
yield self._response
def __aiter__(self) -> AsyncIterator[instance.AppProfile]:
@@ -184,7 +225,9 @@ def __init__(
request: bigtable_instance_admin.ListHotTabletsRequest,
response: bigtable_instance_admin.ListHotTabletsResponse,
*,
- metadata: Sequence[Tuple[str, str]] = ()
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
):
"""Instantiate the pager.
@@ -195,12 +238,19 @@ def __init__(
The initial request object.
response (google.cloud.bigtable_admin_v2.types.ListHotTabletsResponse):
The initial response object.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ retry (google.api_core.retry.Retry): Designation of what errors,
+ if any, should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
"""
self._method = method
self._request = bigtable_instance_admin.ListHotTabletsRequest(request)
self._response = response
+ self._retry = retry
+ self._timeout = timeout
self._metadata = metadata
def __getattr__(self, name: str) -> Any:
@@ -211,7 +261,12 @@ def pages(self) -> Iterator[bigtable_instance_admin.ListHotTabletsResponse]:
yield self._response
while self._response.next_page_token:
self._request.page_token = self._response.next_page_token
- self._response = self._method(self._request, metadata=self._metadata)
+ self._response = self._method(
+ self._request,
+ retry=self._retry,
+ timeout=self._timeout,
+ metadata=self._metadata,
+ )
yield self._response
def __iter__(self) -> Iterator[instance.HotTablet]:
@@ -248,7 +303,9 @@ def __init__(
request: bigtable_instance_admin.ListHotTabletsRequest,
response: bigtable_instance_admin.ListHotTabletsResponse,
*,
- metadata: Sequence[Tuple[str, str]] = ()
+ retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
):
"""Instantiates the pager.
@@ -259,12 +316,19 @@ def __init__(
The initial request object.
response (google.cloud.bigtable_admin_v2.types.ListHotTabletsResponse):
The initial response object.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ retry (google.api_core.retry.AsyncRetry): Designation of what errors,
+ if any, should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
"""
self._method = method
self._request = bigtable_instance_admin.ListHotTabletsRequest(request)
self._response = response
+ self._retry = retry
+ self._timeout = timeout
self._metadata = metadata
def __getattr__(self, name: str) -> Any:
@@ -277,7 +341,12 @@ async def pages(
yield self._response
while self._response.next_page_token:
self._request.page_token = self._response.next_page_token
- self._response = await self._method(self._request, metadata=self._metadata)
+ self._response = await self._method(
+ self._request,
+ retry=self._retry,
+ timeout=self._timeout,
+ metadata=self._metadata,
+ )
yield self._response
def __aiter__(self) -> AsyncIterator[instance.HotTablet]:
@@ -290,3 +359,323 @@ async def async_generator():
def __repr__(self) -> str:
return "{0}<{1!r}>".format(self.__class__.__name__, self._response)
+
+
+class ListLogicalViewsPager:
+ """A pager for iterating through ``list_logical_views`` requests.
+
+ This class thinly wraps an initial
+ :class:`google.cloud.bigtable_admin_v2.types.ListLogicalViewsResponse` object, and
+ provides an ``__iter__`` method to iterate through its
+ ``logical_views`` field.
+
+ If there are more pages, the ``__iter__`` method will make additional
+ ``ListLogicalViews`` requests and continue to iterate
+ through the ``logical_views`` field on the
+ corresponding responses.
+
+ All the usual :class:`google.cloud.bigtable_admin_v2.types.ListLogicalViewsResponse`
+ attributes are available on the pager. If multiple requests are made, only
+ the most recent response is retained, and thus used for attribute lookup.
+ """
+
+ def __init__(
+ self,
+ method: Callable[..., bigtable_instance_admin.ListLogicalViewsResponse],
+ request: bigtable_instance_admin.ListLogicalViewsRequest,
+ response: bigtable_instance_admin.ListLogicalViewsResponse,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
+ ):
+ """Instantiate the pager.
+
+ Args:
+ method (Callable): The method that was originally called, and
+ which instantiated this pager.
+ request (google.cloud.bigtable_admin_v2.types.ListLogicalViewsRequest):
+ The initial request object.
+ response (google.cloud.bigtable_admin_v2.types.ListLogicalViewsResponse):
+ The initial response object.
+ retry (google.api_core.retry.Retry): Designation of what errors,
+ if any, should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+ """
+ self._method = method
+ self._request = bigtable_instance_admin.ListLogicalViewsRequest(request)
+ self._response = response
+ self._retry = retry
+ self._timeout = timeout
+ self._metadata = metadata
+
+ def __getattr__(self, name: str) -> Any:
+ return getattr(self._response, name)
+
+ @property
+ def pages(self) -> Iterator[bigtable_instance_admin.ListLogicalViewsResponse]:
+ yield self._response
+ while self._response.next_page_token:
+ self._request.page_token = self._response.next_page_token
+ self._response = self._method(
+ self._request,
+ retry=self._retry,
+ timeout=self._timeout,
+ metadata=self._metadata,
+ )
+ yield self._response
+
+ def __iter__(self) -> Iterator[instance.LogicalView]:
+ for page in self.pages:
+ yield from page.logical_views
+
+ def __repr__(self) -> str:
+ return "{0}<{1!r}>".format(self.__class__.__name__, self._response)
+
+
+class ListLogicalViewsAsyncPager:
+ """A pager for iterating through ``list_logical_views`` requests.
+
+ This class thinly wraps an initial
+ :class:`google.cloud.bigtable_admin_v2.types.ListLogicalViewsResponse` object, and
+ provides an ``__aiter__`` method to iterate through its
+ ``logical_views`` field.
+
+ If there are more pages, the ``__aiter__`` method will make additional
+ ``ListLogicalViews`` requests and continue to iterate
+ through the ``logical_views`` field on the
+ corresponding responses.
+
+ All the usual :class:`google.cloud.bigtable_admin_v2.types.ListLogicalViewsResponse`
+ attributes are available on the pager. If multiple requests are made, only
+ the most recent response is retained, and thus used for attribute lookup.
+ """
+
+ def __init__(
+ self,
+ method: Callable[
+ ..., Awaitable[bigtable_instance_admin.ListLogicalViewsResponse]
+ ],
+ request: bigtable_instance_admin.ListLogicalViewsRequest,
+ response: bigtable_instance_admin.ListLogicalViewsResponse,
+ *,
+ retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
+ ):
+ """Instantiates the pager.
+
+ Args:
+ method (Callable): The method that was originally called, and
+ which instantiated this pager.
+ request (google.cloud.bigtable_admin_v2.types.ListLogicalViewsRequest):
+ The initial request object.
+ response (google.cloud.bigtable_admin_v2.types.ListLogicalViewsResponse):
+ The initial response object.
+ retry (google.api_core.retry.AsyncRetry): Designation of what errors,
+ if any, should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+ """
+ self._method = method
+ self._request = bigtable_instance_admin.ListLogicalViewsRequest(request)
+ self._response = response
+ self._retry = retry
+ self._timeout = timeout
+ self._metadata = metadata
+
+ def __getattr__(self, name: str) -> Any:
+ return getattr(self._response, name)
+
+ @property
+ async def pages(
+ self,
+ ) -> AsyncIterator[bigtable_instance_admin.ListLogicalViewsResponse]:
+ yield self._response
+ while self._response.next_page_token:
+ self._request.page_token = self._response.next_page_token
+ self._response = await self._method(
+ self._request,
+ retry=self._retry,
+ timeout=self._timeout,
+ metadata=self._metadata,
+ )
+ yield self._response
+
+ def __aiter__(self) -> AsyncIterator[instance.LogicalView]:
+ async def async_generator():
+ async for page in self.pages:
+ for response in page.logical_views:
+ yield response
+
+ return async_generator()
+
+ def __repr__(self) -> str:
+ return "{0}<{1!r}>".format(self.__class__.__name__, self._response)
+
+
+class ListMaterializedViewsPager:
+ """A pager for iterating through ``list_materialized_views`` requests.
+
+ This class thinly wraps an initial
+ :class:`google.cloud.bigtable_admin_v2.types.ListMaterializedViewsResponse` object, and
+ provides an ``__iter__`` method to iterate through its
+ ``materialized_views`` field.
+
+ If there are more pages, the ``__iter__`` method will make additional
+ ``ListMaterializedViews`` requests and continue to iterate
+ through the ``materialized_views`` field on the
+ corresponding responses.
+
+ All the usual :class:`google.cloud.bigtable_admin_v2.types.ListMaterializedViewsResponse`
+ attributes are available on the pager. If multiple requests are made, only
+ the most recent response is retained, and thus used for attribute lookup.
+ """
+
+ def __init__(
+ self,
+ method: Callable[..., bigtable_instance_admin.ListMaterializedViewsResponse],
+ request: bigtable_instance_admin.ListMaterializedViewsRequest,
+ response: bigtable_instance_admin.ListMaterializedViewsResponse,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
+ ):
+ """Instantiate the pager.
+
+ Args:
+ method (Callable): The method that was originally called, and
+ which instantiated this pager.
+ request (google.cloud.bigtable_admin_v2.types.ListMaterializedViewsRequest):
+ The initial request object.
+ response (google.cloud.bigtable_admin_v2.types.ListMaterializedViewsResponse):
+ The initial response object.
+ retry (google.api_core.retry.Retry): Designation of what errors,
+ if any, should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+ """
+ self._method = method
+ self._request = bigtable_instance_admin.ListMaterializedViewsRequest(request)
+ self._response = response
+ self._retry = retry
+ self._timeout = timeout
+ self._metadata = metadata
+
+ def __getattr__(self, name: str) -> Any:
+ return getattr(self._response, name)
+
+ @property
+ def pages(self) -> Iterator[bigtable_instance_admin.ListMaterializedViewsResponse]:
+ yield self._response
+ while self._response.next_page_token:
+ self._request.page_token = self._response.next_page_token
+ self._response = self._method(
+ self._request,
+ retry=self._retry,
+ timeout=self._timeout,
+ metadata=self._metadata,
+ )
+ yield self._response
+
+ def __iter__(self) -> Iterator[instance.MaterializedView]:
+ for page in self.pages:
+ yield from page.materialized_views
+
+ def __repr__(self) -> str:
+ return "{0}<{1!r}>".format(self.__class__.__name__, self._response)
+
+
+class ListMaterializedViewsAsyncPager:
+ """A pager for iterating through ``list_materialized_views`` requests.
+
+ This class thinly wraps an initial
+ :class:`google.cloud.bigtable_admin_v2.types.ListMaterializedViewsResponse` object, and
+ provides an ``__aiter__`` method to iterate through its
+ ``materialized_views`` field.
+
+ If there are more pages, the ``__aiter__`` method will make additional
+ ``ListMaterializedViews`` requests and continue to iterate
+ through the ``materialized_views`` field on the
+ corresponding responses.
+
+ All the usual :class:`google.cloud.bigtable_admin_v2.types.ListMaterializedViewsResponse`
+ attributes are available on the pager. If multiple requests are made, only
+ the most recent response is retained, and thus used for attribute lookup.
+ """
+
+ def __init__(
+ self,
+ method: Callable[
+ ..., Awaitable[bigtable_instance_admin.ListMaterializedViewsResponse]
+ ],
+ request: bigtable_instance_admin.ListMaterializedViewsRequest,
+ response: bigtable_instance_admin.ListMaterializedViewsResponse,
+ *,
+ retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
+ ):
+ """Instantiates the pager.
+
+ Args:
+ method (Callable): The method that was originally called, and
+ which instantiated this pager.
+ request (google.cloud.bigtable_admin_v2.types.ListMaterializedViewsRequest):
+ The initial request object.
+ response (google.cloud.bigtable_admin_v2.types.ListMaterializedViewsResponse):
+ The initial response object.
+ retry (google.api_core.retry.AsyncRetry): Designation of what errors,
+ if any, should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+ """
+ self._method = method
+ self._request = bigtable_instance_admin.ListMaterializedViewsRequest(request)
+ self._response = response
+ self._retry = retry
+ self._timeout = timeout
+ self._metadata = metadata
+
+ def __getattr__(self, name: str) -> Any:
+ return getattr(self._response, name)
+
+ @property
+ async def pages(
+ self,
+ ) -> AsyncIterator[bigtable_instance_admin.ListMaterializedViewsResponse]:
+ yield self._response
+ while self._response.next_page_token:
+ self._request.page_token = self._response.next_page_token
+ self._response = await self._method(
+ self._request,
+ retry=self._retry,
+ timeout=self._timeout,
+ metadata=self._metadata,
+ )
+ yield self._response
+
+ def __aiter__(self) -> AsyncIterator[instance.MaterializedView]:
+ async def async_generator():
+ async for page in self.pages:
+ for response in page.materialized_views:
+ yield response
+
+ return async_generator()
+
+ def __repr__(self) -> str:
+ return "{0}<{1!r}>".format(self.__class__.__name__, self._response)
diff --git a/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/README.rst b/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/README.rst
new file mode 100644
index 000000000..9a01ee7c3
--- /dev/null
+++ b/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/README.rst
@@ -0,0 +1,9 @@
+
+transport inheritance structure
+_______________________________
+
+`BigtableInstanceAdminTransport` is the ABC for all transports.
+- public child `BigtableInstanceAdminGrpcTransport` for sync gRPC transport (defined in `grpc.py`).
+- public child `BigtableInstanceAdminGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`).
+- private child `_BaseBigtableInstanceAdminRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`).
+- public child `BigtableInstanceAdminRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`).
diff --git a/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/__init__.py b/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/__init__.py
index bf207fb3a..021458f35 100644
--- a/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/__init__.py
+++ b/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/__init__.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -19,6 +19,8 @@
from .base import BigtableInstanceAdminTransport
from .grpc import BigtableInstanceAdminGrpcTransport
from .grpc_asyncio import BigtableInstanceAdminGrpcAsyncIOTransport
+from .rest import BigtableInstanceAdminRestTransport
+from .rest import BigtableInstanceAdminRestInterceptor
# Compile a registry of transports.
@@ -27,9 +29,12 @@
) # type: Dict[str, Type[BigtableInstanceAdminTransport]]
_transport_registry["grpc"] = BigtableInstanceAdminGrpcTransport
_transport_registry["grpc_asyncio"] = BigtableInstanceAdminGrpcAsyncIOTransport
+_transport_registry["rest"] = BigtableInstanceAdminRestTransport
__all__ = (
"BigtableInstanceAdminTransport",
"BigtableInstanceAdminGrpcTransport",
"BigtableInstanceAdminGrpcAsyncIOTransport",
+ "BigtableInstanceAdminRestTransport",
+ "BigtableInstanceAdminRestInterceptor",
)
diff --git a/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/base.py b/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/base.py
index 32261ac7b..3a05dd663 100644
--- a/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/base.py
+++ b/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/base.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -15,7 +15,8 @@
#
import abc
from typing import Awaitable, Callable, Dict, Optional, Sequence, Union
-import pkg_resources
+
+from google.cloud.bigtable_admin_v2 import gapic_version as package_version
import google.auth # type: ignore
import google.api_core
@@ -25,6 +26,7 @@
from google.api_core import operations_v1
from google.auth import credentials as ga_credentials # type: ignore
from google.oauth2 import service_account # type: ignore
+import google.protobuf
from google.cloud.bigtable_admin_v2.types import bigtable_instance_admin
from google.cloud.bigtable_admin_v2.types import instance
@@ -33,14 +35,12 @@
from google.longrunning import operations_pb2 # type: ignore
from google.protobuf import empty_pb2 # type: ignore
-try:
- DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
- gapic_version=pkg_resources.get_distribution(
- "google-cloud-bigtable-admin",
- ).version,
- )
-except pkg_resources.DistributionNotFound:
- DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
+DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
+ gapic_version=package_version.__version__
+)
+
+if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER
+ DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__
class BigtableInstanceAdminTransport(abc.ABC):
@@ -62,27 +62,29 @@ def __init__(
self,
*,
host: str = DEFAULT_HOST,
- credentials: ga_credentials.Credentials = None,
+ credentials: Optional[ga_credentials.Credentials] = None,
credentials_file: Optional[str] = None,
scopes: Optional[Sequence[str]] = None,
quota_project_id: Optional[str] = None,
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
always_use_jwt_access: Optional[bool] = False,
+ api_audience: Optional[str] = None,
**kwargs,
) -> None:
"""Instantiate the transport.
Args:
host (Optional[str]):
- The hostname to connect to.
+ The hostname to connect to (default: 'bigtableadmin.googleapis.com').
credentials (Optional[google.auth.credentials.Credentials]): The
authorization credentials to attach to requests. These
credentials identify the application to the service; if none
are specified, the client will attempt to ascertain the
credentials from the environment.
- credentials_file (Optional[str]): A file with credentials that can
+ credentials_file (Optional[str]): Deprecated. A file with credentials that can
be loaded with :func:`google.auth.load_credentials_from_file`.
- This argument is mutually exclusive with credentials.
+ This argument is mutually exclusive with credentials. This argument will be
+ removed in the next major version of this library.
scopes (Optional[Sequence[str]]): A list of scopes.
quota_project_id (Optional[str]): An optional project to use for billing
and quota.
@@ -95,15 +97,12 @@ def __init__(
be used for service account credentials.
"""
- # Save the hostname. Default to port 443 (HTTPS) if none is specified.
- if ":" not in host:
- host += ":443"
- self._host = host
-
scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES}
# Save the scopes.
self._scopes = scopes
+ if not hasattr(self, "_ignore_credentials"):
+ self._ignore_credentials: bool = False
# If no credentials are provided, then determine the appropriate
# defaults.
@@ -116,10 +115,15 @@ def __init__(
credentials, _ = google.auth.load_credentials_from_file(
credentials_file, **scopes_kwargs, quota_project_id=quota_project_id
)
- elif credentials is None:
+ elif credentials is None and not self._ignore_credentials:
credentials, _ = google.auth.default(
**scopes_kwargs, quota_project_id=quota_project_id
)
+ # Don't apply audience if the credentials file passed from user.
+ if hasattr(credentials, "with_gdch_audience"):
+ credentials = credentials.with_gdch_audience(
+ api_audience if api_audience else host
+ )
# If the credentials are service account credentials, then always try to use self signed JWT.
if (
@@ -132,6 +136,15 @@ def __init__(
# Save the credentials.
self._credentials = credentials
+ # Save the hostname. Default to port 443 (HTTPS) if none is specified.
+ if ":" not in host:
+ host += ":443"
+ self._host = host
+
+ @property
+ def host(self):
+ return self._host
+
def _prep_wrapped_messages(self, client_info):
# Precompute the wrapped methods.
self._wrapped_methods = {
@@ -370,6 +383,56 @@ def _prep_wrapped_messages(self, client_info):
default_timeout=60.0,
client_info=client_info,
),
+ self.create_logical_view: gapic_v1.method.wrap_method(
+ self.create_logical_view,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.get_logical_view: gapic_v1.method.wrap_method(
+ self.get_logical_view,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.list_logical_views: gapic_v1.method.wrap_method(
+ self.list_logical_views,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.update_logical_view: gapic_v1.method.wrap_method(
+ self.update_logical_view,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.delete_logical_view: gapic_v1.method.wrap_method(
+ self.delete_logical_view,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.create_materialized_view: gapic_v1.method.wrap_method(
+ self.create_materialized_view,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.get_materialized_view: gapic_v1.method.wrap_method(
+ self.get_materialized_view,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.list_materialized_views: gapic_v1.method.wrap_method(
+ self.list_materialized_views,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.update_materialized_view: gapic_v1.method.wrap_method(
+ self.update_materialized_view,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.delete_materialized_view: gapic_v1.method.wrap_method(
+ self.delete_materialized_view,
+ default_timeout=None,
+ client_info=client_info,
+ ),
}
def close(self):
@@ -589,6 +652,102 @@ def list_hot_tablets(
]:
raise NotImplementedError()
+ @property
+ def create_logical_view(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.CreateLogicalViewRequest],
+ Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def get_logical_view(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.GetLogicalViewRequest],
+ Union[instance.LogicalView, Awaitable[instance.LogicalView]],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def list_logical_views(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.ListLogicalViewsRequest],
+ Union[
+ bigtable_instance_admin.ListLogicalViewsResponse,
+ Awaitable[bigtable_instance_admin.ListLogicalViewsResponse],
+ ],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def update_logical_view(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.UpdateLogicalViewRequest],
+ Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def delete_logical_view(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.DeleteLogicalViewRequest],
+ Union[empty_pb2.Empty, Awaitable[empty_pb2.Empty]],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def create_materialized_view(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.CreateMaterializedViewRequest],
+ Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def get_materialized_view(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.GetMaterializedViewRequest],
+ Union[instance.MaterializedView, Awaitable[instance.MaterializedView]],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def list_materialized_views(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.ListMaterializedViewsRequest],
+ Union[
+ bigtable_instance_admin.ListMaterializedViewsResponse,
+ Awaitable[bigtable_instance_admin.ListMaterializedViewsResponse],
+ ],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def update_materialized_view(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.UpdateMaterializedViewRequest],
+ Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def delete_materialized_view(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.DeleteMaterializedViewRequest],
+ Union[empty_pb2.Empty, Awaitable[empty_pb2.Empty]],
+ ]:
+ raise NotImplementedError()
+
@property
def kind(self) -> str:
raise NotImplementedError()
diff --git a/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/grpc.py b/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/grpc.py
index db7d0c1c4..d5d5cf1e5 100644
--- a/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/grpc.py
+++ b/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/grpc.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -13,6 +13,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+import json
+import logging as std_logging
+import pickle
import warnings
from typing import Callable, Dict, Optional, Sequence, Tuple, Union
@@ -22,8 +25,11 @@
import google.auth # type: ignore
from google.auth import credentials as ga_credentials # type: ignore
from google.auth.transport.grpc import SslCredentials # type: ignore
+from google.protobuf.json_format import MessageToJson
+import google.protobuf.message
import grpc # type: ignore
+import proto # type: ignore
from google.cloud.bigtable_admin_v2.types import bigtable_instance_admin
from google.cloud.bigtable_admin_v2.types import instance
@@ -33,6 +39,80 @@
from google.protobuf import empty_pb2 # type: ignore
from .base import BigtableInstanceAdminTransport, DEFAULT_CLIENT_INFO
+try:
+ from google.api_core import client_logging # type: ignore
+
+ CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER
+except ImportError: # pragma: NO COVER
+ CLIENT_LOGGING_SUPPORTED = False
+
+_LOGGER = std_logging.getLogger(__name__)
+
+
+class _LoggingClientInterceptor(grpc.UnaryUnaryClientInterceptor): # pragma: NO COVER
+ def intercept_unary_unary(self, continuation, client_call_details, request):
+ logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ std_logging.DEBUG
+ )
+ if logging_enabled: # pragma: NO COVER
+ request_metadata = client_call_details.metadata
+ if isinstance(request, proto.Message):
+ request_payload = type(request).to_json(request)
+ elif isinstance(request, google.protobuf.message.Message):
+ request_payload = MessageToJson(request)
+ else:
+ request_payload = f"{type(request).__name__}: {pickle.dumps(request)}"
+
+ request_metadata = {
+ key: value.decode("utf-8") if isinstance(value, bytes) else value
+ for key, value in request_metadata
+ }
+ grpc_request = {
+ "payload": request_payload,
+ "requestMethod": "grpc",
+ "metadata": dict(request_metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for {client_call_details.method}",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": str(client_call_details.method),
+ "request": grpc_request,
+ "metadata": grpc_request["metadata"],
+ },
+ )
+ response = continuation(client_call_details, request)
+ if logging_enabled: # pragma: NO COVER
+ response_metadata = response.trailing_metadata()
+ # Convert gRPC metadata `` to list of tuples
+ metadata = (
+ dict([(k, str(v)) for k, v in response_metadata])
+ if response_metadata
+ else None
+ )
+ result = response.result()
+ if isinstance(result, proto.Message):
+ response_payload = type(result).to_json(result)
+ elif isinstance(result, google.protobuf.message.Message):
+ response_payload = MessageToJson(result)
+ else:
+ response_payload = f"{type(result).__name__}: {pickle.dumps(result)}"
+ grpc_response = {
+ "payload": response_payload,
+ "metadata": metadata,
+ "status": "OK",
+ }
+ _LOGGER.debug(
+ f"Received response for {client_call_details.method}.",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": client_call_details.method,
+ "response": grpc_response,
+ "metadata": grpc_response["metadata"],
+ },
+ )
+ return response
+
class BigtableInstanceAdminGrpcTransport(BigtableInstanceAdminTransport):
"""gRPC backend transport for BigtableInstanceAdmin.
@@ -56,36 +136,41 @@ def __init__(
self,
*,
host: str = "bigtableadmin.googleapis.com",
- credentials: ga_credentials.Credentials = None,
- credentials_file: str = None,
- scopes: Sequence[str] = None,
- channel: grpc.Channel = None,
- api_mtls_endpoint: str = None,
- client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
- ssl_channel_credentials: grpc.ChannelCredentials = None,
- client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None,
+ credentials: Optional[ga_credentials.Credentials] = None,
+ credentials_file: Optional[str] = None,
+ scopes: Optional[Sequence[str]] = None,
+ channel: Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]] = None,
+ api_mtls_endpoint: Optional[str] = None,
+ client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None,
+ ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None,
+ client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None,
quota_project_id: Optional[str] = None,
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
always_use_jwt_access: Optional[bool] = False,
+ api_audience: Optional[str] = None,
) -> None:
"""Instantiate the transport.
Args:
host (Optional[str]):
- The hostname to connect to.
+ The hostname to connect to (default: 'bigtableadmin.googleapis.com').
credentials (Optional[google.auth.credentials.Credentials]): The
authorization credentials to attach to requests. These
credentials identify the application to the service; if none
are specified, the client will attempt to ascertain the
credentials from the environment.
- This argument is ignored if ``channel`` is provided.
- credentials_file (Optional[str]): A file with credentials that can
+ This argument is ignored if a ``channel`` instance is provided.
+ credentials_file (Optional[str]): Deprecated. A file with credentials that can
be loaded with :func:`google.auth.load_credentials_from_file`.
- This argument is ignored if ``channel`` is provided.
+ This argument is ignored if a ``channel`` instance is provided.
+ This argument will be removed in the next major version of this library.
scopes (Optional(Sequence[str])): A list of scopes. This argument is
- ignored if ``channel`` is provided.
- channel (Optional[grpc.Channel]): A ``Channel`` instance through
- which to make calls.
+ ignored if a ``channel`` instance is provided.
+ channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]):
+ A ``Channel`` instance through which to make calls, or a Callable
+ that constructs and returns one. If set to None, ``self.create_channel``
+ is used to create the channel. If a Callable is given, it will be called
+ with the same arguments as used in ``self.create_channel``.
api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
If provided, it overrides the ``host`` argument and tries to create
a mutual TLS channel with client SSL credentials from
@@ -95,11 +180,11 @@ def __init__(
private key bytes, both in PEM format. It is ignored if
``api_mtls_endpoint`` is None.
ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
- for the grpc channel. It is ignored if ``channel`` is provided.
+ for the grpc channel. It is ignored if a ``channel`` instance is provided.
client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]):
A callback to provide client certificate bytes and private key bytes,
both in PEM format. It is used to configure a mutual TLS channel. It is
- ignored if ``channel`` or ``ssl_channel_credentials`` is provided.
+ ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided.
quota_project_id (Optional[str]): An optional project to use for billing
and quota.
client_info (google.api_core.gapic_v1.client_info.ClientInfo):
@@ -126,9 +211,10 @@ def __init__(
if client_cert_source:
warnings.warn("client_cert_source is deprecated", DeprecationWarning)
- if channel:
+ if isinstance(channel, grpc.Channel):
# Ignore credentials if a channel was passed.
- credentials = False
+ credentials = None
+ self._ignore_credentials = True
# If a channel was explicitly provided, set it.
self._grpc_channel = channel
self._ssl_channel_credentials = None
@@ -163,10 +249,13 @@ def __init__(
quota_project_id=quota_project_id,
client_info=client_info,
always_use_jwt_access=always_use_jwt_access,
+ api_audience=api_audience,
)
if not self._grpc_channel:
- self._grpc_channel = type(self).create_channel(
+ # initialize with the provided callable or the default channel
+ channel_init = channel or type(self).create_channel
+ self._grpc_channel = channel_init(
self._host,
# use the credentials which are saved
credentials=self._credentials,
@@ -182,15 +271,20 @@ def __init__(
],
)
- # Wrap messages. This must be done after self._grpc_channel exists
+ self._interceptor = _LoggingClientInterceptor()
+ self._logged_channel = grpc.intercept_channel(
+ self._grpc_channel, self._interceptor
+ )
+
+ # Wrap messages. This must be done after self._logged_channel exists
self._prep_wrapped_messages(client_info)
@classmethod
def create_channel(
cls,
host: str = "bigtableadmin.googleapis.com",
- credentials: ga_credentials.Credentials = None,
- credentials_file: str = None,
+ credentials: Optional[ga_credentials.Credentials] = None,
+ credentials_file: Optional[str] = None,
scopes: Optional[Sequence[str]] = None,
quota_project_id: Optional[str] = None,
**kwargs,
@@ -203,9 +297,10 @@ def create_channel(
credentials identify this application to the service. If
none are specified, the client will attempt to ascertain
the credentials from the environment.
- credentials_file (Optional[str]): A file with credentials that can
+ credentials_file (Optional[str]): Deprecated. A file with credentials that can
be loaded with :func:`google.auth.load_credentials_from_file`.
- This argument is mutually exclusive with credentials.
+ This argument is mutually exclusive with credentials. This argument will be
+ removed in the next major version of this library.
scopes (Optional[Sequence[str]]): A optional list of scopes needed for this
service. These are only used when credentials are not specified and
are passed to :func:`google.auth.default`.
@@ -246,7 +341,9 @@ def operations_client(self) -> operations_v1.OperationsClient:
"""
# Quick check: Only create a new client if we do not already have one.
if self._operations_client is None:
- self._operations_client = operations_v1.OperationsClient(self.grpc_channel)
+ self._operations_client = operations_v1.OperationsClient(
+ self._logged_channel
+ )
# Return the client from cache.
return self._operations_client
@@ -278,7 +375,7 @@ def create_instance(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "create_instance" not in self._stubs:
- self._stubs["create_instance"] = self.grpc_channel.unary_unary(
+ self._stubs["create_instance"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/CreateInstance",
request_serializer=bigtable_instance_admin.CreateInstanceRequest.serialize,
response_deserializer=operations_pb2.Operation.FromString,
@@ -304,7 +401,7 @@ def get_instance(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "get_instance" not in self._stubs:
- self._stubs["get_instance"] = self.grpc_channel.unary_unary(
+ self._stubs["get_instance"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/GetInstance",
request_serializer=bigtable_instance_admin.GetInstanceRequest.serialize,
response_deserializer=instance.Instance.deserialize,
@@ -333,7 +430,7 @@ def list_instances(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "list_instances" not in self._stubs:
- self._stubs["list_instances"] = self.grpc_channel.unary_unary(
+ self._stubs["list_instances"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/ListInstances",
request_serializer=bigtable_instance_admin.ListInstancesRequest.serialize,
response_deserializer=bigtable_instance_admin.ListInstancesResponse.deserialize,
@@ -360,7 +457,7 @@ def update_instance(self) -> Callable[[instance.Instance], instance.Instance]:
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "update_instance" not in self._stubs:
- self._stubs["update_instance"] = self.grpc_channel.unary_unary(
+ self._stubs["update_instance"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/UpdateInstance",
request_serializer=instance.Instance.serialize,
response_deserializer=instance.Instance.deserialize,
@@ -390,7 +487,7 @@ def partial_update_instance(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "partial_update_instance" not in self._stubs:
- self._stubs["partial_update_instance"] = self.grpc_channel.unary_unary(
+ self._stubs["partial_update_instance"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/PartialUpdateInstance",
request_serializer=bigtable_instance_admin.PartialUpdateInstanceRequest.serialize,
response_deserializer=operations_pb2.Operation.FromString,
@@ -416,7 +513,7 @@ def delete_instance(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "delete_instance" not in self._stubs:
- self._stubs["delete_instance"] = self.grpc_channel.unary_unary(
+ self._stubs["delete_instance"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/DeleteInstance",
request_serializer=bigtable_instance_admin.DeleteInstanceRequest.serialize,
response_deserializer=empty_pb2.Empty.FromString,
@@ -450,7 +547,7 @@ def create_cluster(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "create_cluster" not in self._stubs:
- self._stubs["create_cluster"] = self.grpc_channel.unary_unary(
+ self._stubs["create_cluster"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/CreateCluster",
request_serializer=bigtable_instance_admin.CreateClusterRequest.serialize,
response_deserializer=operations_pb2.Operation.FromString,
@@ -476,7 +573,7 @@ def get_cluster(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "get_cluster" not in self._stubs:
- self._stubs["get_cluster"] = self.grpc_channel.unary_unary(
+ self._stubs["get_cluster"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/GetCluster",
request_serializer=bigtable_instance_admin.GetClusterRequest.serialize,
response_deserializer=instance.Cluster.deserialize,
@@ -505,7 +602,7 @@ def list_clusters(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "list_clusters" not in self._stubs:
- self._stubs["list_clusters"] = self.grpc_channel.unary_unary(
+ self._stubs["list_clusters"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/ListClusters",
request_serializer=bigtable_instance_admin.ListClustersRequest.serialize,
response_deserializer=bigtable_instance_admin.ListClustersResponse.deserialize,
@@ -533,7 +630,7 @@ def update_cluster(self) -> Callable[[instance.Cluster], operations_pb2.Operatio
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "update_cluster" not in self._stubs:
- self._stubs["update_cluster"] = self.grpc_channel.unary_unary(
+ self._stubs["update_cluster"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/UpdateCluster",
request_serializer=instance.Cluster.serialize,
response_deserializer=operations_pb2.Operation.FromString,
@@ -574,7 +671,7 @@ def partial_update_cluster(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "partial_update_cluster" not in self._stubs:
- self._stubs["partial_update_cluster"] = self.grpc_channel.unary_unary(
+ self._stubs["partial_update_cluster"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/PartialUpdateCluster",
request_serializer=bigtable_instance_admin.PartialUpdateClusterRequest.serialize,
response_deserializer=operations_pb2.Operation.FromString,
@@ -600,7 +697,7 @@ def delete_cluster(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "delete_cluster" not in self._stubs:
- self._stubs["delete_cluster"] = self.grpc_channel.unary_unary(
+ self._stubs["delete_cluster"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/DeleteCluster",
request_serializer=bigtable_instance_admin.DeleteClusterRequest.serialize,
response_deserializer=empty_pb2.Empty.FromString,
@@ -628,7 +725,7 @@ def create_app_profile(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "create_app_profile" not in self._stubs:
- self._stubs["create_app_profile"] = self.grpc_channel.unary_unary(
+ self._stubs["create_app_profile"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/CreateAppProfile",
request_serializer=bigtable_instance_admin.CreateAppProfileRequest.serialize,
response_deserializer=instance.AppProfile.deserialize,
@@ -654,7 +751,7 @@ def get_app_profile(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "get_app_profile" not in self._stubs:
- self._stubs["get_app_profile"] = self.grpc_channel.unary_unary(
+ self._stubs["get_app_profile"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/GetAppProfile",
request_serializer=bigtable_instance_admin.GetAppProfileRequest.serialize,
response_deserializer=instance.AppProfile.deserialize,
@@ -683,7 +780,7 @@ def list_app_profiles(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "list_app_profiles" not in self._stubs:
- self._stubs["list_app_profiles"] = self.grpc_channel.unary_unary(
+ self._stubs["list_app_profiles"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/ListAppProfiles",
request_serializer=bigtable_instance_admin.ListAppProfilesRequest.serialize,
response_deserializer=bigtable_instance_admin.ListAppProfilesResponse.deserialize,
@@ -711,7 +808,7 @@ def update_app_profile(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "update_app_profile" not in self._stubs:
- self._stubs["update_app_profile"] = self.grpc_channel.unary_unary(
+ self._stubs["update_app_profile"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/UpdateAppProfile",
request_serializer=bigtable_instance_admin.UpdateAppProfileRequest.serialize,
response_deserializer=operations_pb2.Operation.FromString,
@@ -737,7 +834,7 @@ def delete_app_profile(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "delete_app_profile" not in self._stubs:
- self._stubs["delete_app_profile"] = self.grpc_channel.unary_unary(
+ self._stubs["delete_app_profile"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/DeleteAppProfile",
request_serializer=bigtable_instance_admin.DeleteAppProfileRequest.serialize,
response_deserializer=empty_pb2.Empty.FromString,
@@ -765,7 +862,7 @@ def get_iam_policy(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "get_iam_policy" not in self._stubs:
- self._stubs["get_iam_policy"] = self.grpc_channel.unary_unary(
+ self._stubs["get_iam_policy"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/GetIamPolicy",
request_serializer=iam_policy_pb2.GetIamPolicyRequest.SerializeToString,
response_deserializer=policy_pb2.Policy.FromString,
@@ -792,7 +889,7 @@ def set_iam_policy(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "set_iam_policy" not in self._stubs:
- self._stubs["set_iam_policy"] = self.grpc_channel.unary_unary(
+ self._stubs["set_iam_policy"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/SetIamPolicy",
request_serializer=iam_policy_pb2.SetIamPolicyRequest.SerializeToString,
response_deserializer=policy_pb2.Policy.FromString,
@@ -822,7 +919,7 @@ def test_iam_permissions(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "test_iam_permissions" not in self._stubs:
- self._stubs["test_iam_permissions"] = self.grpc_channel.unary_unary(
+ self._stubs["test_iam_permissions"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/TestIamPermissions",
request_serializer=iam_policy_pb2.TestIamPermissionsRequest.SerializeToString,
response_deserializer=iam_policy_pb2.TestIamPermissionsResponse.FromString,
@@ -852,15 +949,298 @@ def list_hot_tablets(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "list_hot_tablets" not in self._stubs:
- self._stubs["list_hot_tablets"] = self.grpc_channel.unary_unary(
+ self._stubs["list_hot_tablets"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/ListHotTablets",
request_serializer=bigtable_instance_admin.ListHotTabletsRequest.serialize,
response_deserializer=bigtable_instance_admin.ListHotTabletsResponse.deserialize,
)
return self._stubs["list_hot_tablets"]
+ @property
+ def create_logical_view(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.CreateLogicalViewRequest], operations_pb2.Operation
+ ]:
+ r"""Return a callable for the create logical view method over gRPC.
+
+ Creates a logical view within an instance.
+
+ Returns:
+ Callable[[~.CreateLogicalViewRequest],
+ ~.Operation]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "create_logical_view" not in self._stubs:
+ self._stubs["create_logical_view"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableInstanceAdmin/CreateLogicalView",
+ request_serializer=bigtable_instance_admin.CreateLogicalViewRequest.serialize,
+ response_deserializer=operations_pb2.Operation.FromString,
+ )
+ return self._stubs["create_logical_view"]
+
+ @property
+ def get_logical_view(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.GetLogicalViewRequest], instance.LogicalView
+ ]:
+ r"""Return a callable for the get logical view method over gRPC.
+
+ Gets information about a logical view.
+
+ Returns:
+ Callable[[~.GetLogicalViewRequest],
+ ~.LogicalView]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "get_logical_view" not in self._stubs:
+ self._stubs["get_logical_view"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableInstanceAdmin/GetLogicalView",
+ request_serializer=bigtable_instance_admin.GetLogicalViewRequest.serialize,
+ response_deserializer=instance.LogicalView.deserialize,
+ )
+ return self._stubs["get_logical_view"]
+
+ @property
+ def list_logical_views(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.ListLogicalViewsRequest],
+ bigtable_instance_admin.ListLogicalViewsResponse,
+ ]:
+ r"""Return a callable for the list logical views method over gRPC.
+
+ Lists information about logical views in an instance.
+
+ Returns:
+ Callable[[~.ListLogicalViewsRequest],
+ ~.ListLogicalViewsResponse]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "list_logical_views" not in self._stubs:
+ self._stubs["list_logical_views"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableInstanceAdmin/ListLogicalViews",
+ request_serializer=bigtable_instance_admin.ListLogicalViewsRequest.serialize,
+ response_deserializer=bigtable_instance_admin.ListLogicalViewsResponse.deserialize,
+ )
+ return self._stubs["list_logical_views"]
+
+ @property
+ def update_logical_view(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.UpdateLogicalViewRequest], operations_pb2.Operation
+ ]:
+ r"""Return a callable for the update logical view method over gRPC.
+
+ Updates a logical view within an instance.
+
+ Returns:
+ Callable[[~.UpdateLogicalViewRequest],
+ ~.Operation]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "update_logical_view" not in self._stubs:
+ self._stubs["update_logical_view"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableInstanceAdmin/UpdateLogicalView",
+ request_serializer=bigtable_instance_admin.UpdateLogicalViewRequest.serialize,
+ response_deserializer=operations_pb2.Operation.FromString,
+ )
+ return self._stubs["update_logical_view"]
+
+ @property
+ def delete_logical_view(
+ self,
+ ) -> Callable[[bigtable_instance_admin.DeleteLogicalViewRequest], empty_pb2.Empty]:
+ r"""Return a callable for the delete logical view method over gRPC.
+
+ Deletes a logical view from an instance.
+
+ Returns:
+ Callable[[~.DeleteLogicalViewRequest],
+ ~.Empty]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "delete_logical_view" not in self._stubs:
+ self._stubs["delete_logical_view"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableInstanceAdmin/DeleteLogicalView",
+ request_serializer=bigtable_instance_admin.DeleteLogicalViewRequest.serialize,
+ response_deserializer=empty_pb2.Empty.FromString,
+ )
+ return self._stubs["delete_logical_view"]
+
+ @property
+ def create_materialized_view(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.CreateMaterializedViewRequest],
+ operations_pb2.Operation,
+ ]:
+ r"""Return a callable for the create materialized view method over gRPC.
+
+ Creates a materialized view within an instance.
+
+ Returns:
+ Callable[[~.CreateMaterializedViewRequest],
+ ~.Operation]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "create_materialized_view" not in self._stubs:
+ self._stubs["create_materialized_view"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableInstanceAdmin/CreateMaterializedView",
+ request_serializer=bigtable_instance_admin.CreateMaterializedViewRequest.serialize,
+ response_deserializer=operations_pb2.Operation.FromString,
+ )
+ return self._stubs["create_materialized_view"]
+
+ @property
+ def get_materialized_view(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.GetMaterializedViewRequest], instance.MaterializedView
+ ]:
+ r"""Return a callable for the get materialized view method over gRPC.
+
+ Gets information about a materialized view.
+
+ Returns:
+ Callable[[~.GetMaterializedViewRequest],
+ ~.MaterializedView]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "get_materialized_view" not in self._stubs:
+ self._stubs["get_materialized_view"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableInstanceAdmin/GetMaterializedView",
+ request_serializer=bigtable_instance_admin.GetMaterializedViewRequest.serialize,
+ response_deserializer=instance.MaterializedView.deserialize,
+ )
+ return self._stubs["get_materialized_view"]
+
+ @property
+ def list_materialized_views(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.ListMaterializedViewsRequest],
+ bigtable_instance_admin.ListMaterializedViewsResponse,
+ ]:
+ r"""Return a callable for the list materialized views method over gRPC.
+
+ Lists information about materialized views in an
+ instance.
+
+ Returns:
+ Callable[[~.ListMaterializedViewsRequest],
+ ~.ListMaterializedViewsResponse]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "list_materialized_views" not in self._stubs:
+ self._stubs["list_materialized_views"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableInstanceAdmin/ListMaterializedViews",
+ request_serializer=bigtable_instance_admin.ListMaterializedViewsRequest.serialize,
+ response_deserializer=bigtable_instance_admin.ListMaterializedViewsResponse.deserialize,
+ )
+ return self._stubs["list_materialized_views"]
+
+ @property
+ def update_materialized_view(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.UpdateMaterializedViewRequest],
+ operations_pb2.Operation,
+ ]:
+ r"""Return a callable for the update materialized view method over gRPC.
+
+ Updates a materialized view within an instance.
+
+ Returns:
+ Callable[[~.UpdateMaterializedViewRequest],
+ ~.Operation]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "update_materialized_view" not in self._stubs:
+ self._stubs["update_materialized_view"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableInstanceAdmin/UpdateMaterializedView",
+ request_serializer=bigtable_instance_admin.UpdateMaterializedViewRequest.serialize,
+ response_deserializer=operations_pb2.Operation.FromString,
+ )
+ return self._stubs["update_materialized_view"]
+
+ @property
+ def delete_materialized_view(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.DeleteMaterializedViewRequest], empty_pb2.Empty
+ ]:
+ r"""Return a callable for the delete materialized view method over gRPC.
+
+ Deletes a materialized view from an instance.
+
+ Returns:
+ Callable[[~.DeleteMaterializedViewRequest],
+ ~.Empty]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "delete_materialized_view" not in self._stubs:
+ self._stubs["delete_materialized_view"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableInstanceAdmin/DeleteMaterializedView",
+ request_serializer=bigtable_instance_admin.DeleteMaterializedViewRequest.serialize,
+ response_deserializer=empty_pb2.Empty.FromString,
+ )
+ return self._stubs["delete_materialized_view"]
+
def close(self):
- self.grpc_channel.close()
+ self._logged_channel.close()
@property
def kind(self) -> str:
diff --git a/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/grpc_asyncio.py b/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/grpc_asyncio.py
index bf1b8a38e..7ce762764 100644
--- a/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/grpc_asyncio.py
+++ b/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/grpc_asyncio.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -13,16 +13,25 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+import inspect
+import json
+import pickle
+import logging as std_logging
import warnings
from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union
from google.api_core import gapic_v1
from google.api_core import grpc_helpers_async
+from google.api_core import exceptions as core_exceptions
+from google.api_core import retry_async as retries
from google.api_core import operations_v1
from google.auth import credentials as ga_credentials # type: ignore
from google.auth.transport.grpc import SslCredentials # type: ignore
+from google.protobuf.json_format import MessageToJson
+import google.protobuf.message
import grpc # type: ignore
+import proto # type: ignore
from grpc.experimental import aio # type: ignore
from google.cloud.bigtable_admin_v2.types import bigtable_instance_admin
@@ -34,6 +43,82 @@
from .base import BigtableInstanceAdminTransport, DEFAULT_CLIENT_INFO
from .grpc import BigtableInstanceAdminGrpcTransport
+try:
+ from google.api_core import client_logging # type: ignore
+
+ CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER
+except ImportError: # pragma: NO COVER
+ CLIENT_LOGGING_SUPPORTED = False
+
+_LOGGER = std_logging.getLogger(__name__)
+
+
+class _LoggingClientAIOInterceptor(
+ grpc.aio.UnaryUnaryClientInterceptor
+): # pragma: NO COVER
+ async def intercept_unary_unary(self, continuation, client_call_details, request):
+ logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ std_logging.DEBUG
+ )
+ if logging_enabled: # pragma: NO COVER
+ request_metadata = client_call_details.metadata
+ if isinstance(request, proto.Message):
+ request_payload = type(request).to_json(request)
+ elif isinstance(request, google.protobuf.message.Message):
+ request_payload = MessageToJson(request)
+ else:
+ request_payload = f"{type(request).__name__}: {pickle.dumps(request)}"
+
+ request_metadata = {
+ key: value.decode("utf-8") if isinstance(value, bytes) else value
+ for key, value in request_metadata
+ }
+ grpc_request = {
+ "payload": request_payload,
+ "requestMethod": "grpc",
+ "metadata": dict(request_metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for {client_call_details.method}",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": str(client_call_details.method),
+ "request": grpc_request,
+ "metadata": grpc_request["metadata"],
+ },
+ )
+ response = await continuation(client_call_details, request)
+ if logging_enabled: # pragma: NO COVER
+ response_metadata = await response.trailing_metadata()
+ # Convert gRPC metadata `` to list of tuples
+ metadata = (
+ dict([(k, str(v)) for k, v in response_metadata])
+ if response_metadata
+ else None
+ )
+ result = await response
+ if isinstance(result, proto.Message):
+ response_payload = type(result).to_json(result)
+ elif isinstance(result, google.protobuf.message.Message):
+ response_payload = MessageToJson(result)
+ else:
+ response_payload = f"{type(result).__name__}: {pickle.dumps(result)}"
+ grpc_response = {
+ "payload": response_payload,
+ "metadata": metadata,
+ "status": "OK",
+ }
+ _LOGGER.debug(
+ f"Received response to rpc {client_call_details.method}.",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": str(client_call_details.method),
+ "response": grpc_response,
+ "metadata": grpc_response["metadata"],
+ },
+ )
+ return response
+
class BigtableInstanceAdminGrpcAsyncIOTransport(BigtableInstanceAdminTransport):
"""gRPC AsyncIO backend transport for BigtableInstanceAdmin.
@@ -58,7 +143,7 @@ class BigtableInstanceAdminGrpcAsyncIOTransport(BigtableInstanceAdminTransport):
def create_channel(
cls,
host: str = "bigtableadmin.googleapis.com",
- credentials: ga_credentials.Credentials = None,
+ credentials: Optional[ga_credentials.Credentials] = None,
credentials_file: Optional[str] = None,
scopes: Optional[Sequence[str]] = None,
quota_project_id: Optional[str] = None,
@@ -72,9 +157,9 @@ def create_channel(
credentials identify this application to the service. If
none are specified, the client will attempt to ascertain
the credentials from the environment.
- credentials_file (Optional[str]): A file with credentials that can
- be loaded with :func:`google.auth.load_credentials_from_file`.
- This argument is ignored if ``channel`` is provided.
+ credentials_file (Optional[str]): Deprecated. A file with credentials that can
+ be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be
+ removed in the next major version of this library.
scopes (Optional[Sequence[str]]): A optional list of scopes needed for this
service. These are only used when credentials are not specified and
are passed to :func:`google.auth.default`.
@@ -101,37 +186,42 @@ def __init__(
self,
*,
host: str = "bigtableadmin.googleapis.com",
- credentials: ga_credentials.Credentials = None,
+ credentials: Optional[ga_credentials.Credentials] = None,
credentials_file: Optional[str] = None,
scopes: Optional[Sequence[str]] = None,
- channel: aio.Channel = None,
- api_mtls_endpoint: str = None,
- client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
- ssl_channel_credentials: grpc.ChannelCredentials = None,
- client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None,
- quota_project_id=None,
+ channel: Optional[Union[aio.Channel, Callable[..., aio.Channel]]] = None,
+ api_mtls_endpoint: Optional[str] = None,
+ client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None,
+ ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None,
+ client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None,
+ quota_project_id: Optional[str] = None,
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
always_use_jwt_access: Optional[bool] = False,
+ api_audience: Optional[str] = None,
) -> None:
"""Instantiate the transport.
Args:
host (Optional[str]):
- The hostname to connect to.
+ The hostname to connect to (default: 'bigtableadmin.googleapis.com').
credentials (Optional[google.auth.credentials.Credentials]): The
authorization credentials to attach to requests. These
credentials identify the application to the service; if none
are specified, the client will attempt to ascertain the
credentials from the environment.
- This argument is ignored if ``channel`` is provided.
- credentials_file (Optional[str]): A file with credentials that can
+ This argument is ignored if a ``channel`` instance is provided.
+ credentials_file (Optional[str]): Deprecated. A file with credentials that can
be loaded with :func:`google.auth.load_credentials_from_file`.
- This argument is ignored if ``channel`` is provided.
+ This argument is ignored if a ``channel`` instance is provided.
+ This argument will be removed in the next major version of this library.
scopes (Optional[Sequence[str]]): A optional list of scopes needed for this
service. These are only used when credentials are not specified and
are passed to :func:`google.auth.default`.
- channel (Optional[aio.Channel]): A ``Channel`` instance through
- which to make calls.
+ channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]):
+ A ``Channel`` instance through which to make calls, or a Callable
+ that constructs and returns one. If set to None, ``self.create_channel``
+ is used to create the channel. If a Callable is given, it will be called
+ with the same arguments as used in ``self.create_channel``.
api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
If provided, it overrides the ``host`` argument and tries to create
a mutual TLS channel with client SSL credentials from
@@ -141,11 +231,11 @@ def __init__(
private key bytes, both in PEM format. It is ignored if
``api_mtls_endpoint`` is None.
ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
- for the grpc channel. It is ignored if ``channel`` is provided.
+ for the grpc channel. It is ignored if a ``channel`` instance is provided.
client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]):
A callback to provide client certificate bytes and private key bytes,
both in PEM format. It is used to configure a mutual TLS channel. It is
- ignored if ``channel`` or ``ssl_channel_credentials`` is provided.
+ ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided.
quota_project_id (Optional[str]): An optional project to use for billing
and quota.
client_info (google.api_core.gapic_v1.client_info.ClientInfo):
@@ -172,9 +262,10 @@ def __init__(
if client_cert_source:
warnings.warn("client_cert_source is deprecated", DeprecationWarning)
- if channel:
+ if isinstance(channel, aio.Channel):
# Ignore credentials if a channel was passed.
- credentials = False
+ credentials = None
+ self._ignore_credentials = True
# If a channel was explicitly provided, set it.
self._grpc_channel = channel
self._ssl_channel_credentials = None
@@ -208,10 +299,13 @@ def __init__(
quota_project_id=quota_project_id,
client_info=client_info,
always_use_jwt_access=always_use_jwt_access,
+ api_audience=api_audience,
)
if not self._grpc_channel:
- self._grpc_channel = type(self).create_channel(
+ # initialize with the provided callable or the default channel
+ channel_init = channel or type(self).create_channel
+ self._grpc_channel = channel_init(
self._host,
# use the credentials which are saved
credentials=self._credentials,
@@ -227,7 +321,13 @@ def __init__(
],
)
- # Wrap messages. This must be done after self._grpc_channel exists
+ self._interceptor = _LoggingClientAIOInterceptor()
+ self._grpc_channel._unary_unary_interceptors.append(self._interceptor)
+ self._logged_channel = self._grpc_channel
+ self._wrap_with_kind = (
+ "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters
+ )
+ # Wrap messages. This must be done after self._logged_channel exists
self._prep_wrapped_messages(client_info)
@property
@@ -250,7 +350,7 @@ def operations_client(self) -> operations_v1.OperationsAsyncClient:
# Quick check: Only create a new client if we do not already have one.
if self._operations_client is None:
self._operations_client = operations_v1.OperationsAsyncClient(
- self.grpc_channel
+ self._logged_channel
)
# Return the client from cache.
@@ -284,7 +384,7 @@ def create_instance(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "create_instance" not in self._stubs:
- self._stubs["create_instance"] = self.grpc_channel.unary_unary(
+ self._stubs["create_instance"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/CreateInstance",
request_serializer=bigtable_instance_admin.CreateInstanceRequest.serialize,
response_deserializer=operations_pb2.Operation.FromString,
@@ -312,7 +412,7 @@ def get_instance(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "get_instance" not in self._stubs:
- self._stubs["get_instance"] = self.grpc_channel.unary_unary(
+ self._stubs["get_instance"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/GetInstance",
request_serializer=bigtable_instance_admin.GetInstanceRequest.serialize,
response_deserializer=instance.Instance.deserialize,
@@ -341,7 +441,7 @@ def list_instances(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "list_instances" not in self._stubs:
- self._stubs["list_instances"] = self.grpc_channel.unary_unary(
+ self._stubs["list_instances"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/ListInstances",
request_serializer=bigtable_instance_admin.ListInstancesRequest.serialize,
response_deserializer=bigtable_instance_admin.ListInstancesResponse.deserialize,
@@ -370,7 +470,7 @@ def update_instance(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "update_instance" not in self._stubs:
- self._stubs["update_instance"] = self.grpc_channel.unary_unary(
+ self._stubs["update_instance"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/UpdateInstance",
request_serializer=instance.Instance.serialize,
response_deserializer=instance.Instance.deserialize,
@@ -401,7 +501,7 @@ def partial_update_instance(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "partial_update_instance" not in self._stubs:
- self._stubs["partial_update_instance"] = self.grpc_channel.unary_unary(
+ self._stubs["partial_update_instance"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/PartialUpdateInstance",
request_serializer=bigtable_instance_admin.PartialUpdateInstanceRequest.serialize,
response_deserializer=operations_pb2.Operation.FromString,
@@ -429,7 +529,7 @@ def delete_instance(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "delete_instance" not in self._stubs:
- self._stubs["delete_instance"] = self.grpc_channel.unary_unary(
+ self._stubs["delete_instance"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/DeleteInstance",
request_serializer=bigtable_instance_admin.DeleteInstanceRequest.serialize,
response_deserializer=empty_pb2.Empty.FromString,
@@ -464,7 +564,7 @@ def create_cluster(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "create_cluster" not in self._stubs:
- self._stubs["create_cluster"] = self.grpc_channel.unary_unary(
+ self._stubs["create_cluster"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/CreateCluster",
request_serializer=bigtable_instance_admin.CreateClusterRequest.serialize,
response_deserializer=operations_pb2.Operation.FromString,
@@ -492,7 +592,7 @@ def get_cluster(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "get_cluster" not in self._stubs:
- self._stubs["get_cluster"] = self.grpc_channel.unary_unary(
+ self._stubs["get_cluster"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/GetCluster",
request_serializer=bigtable_instance_admin.GetClusterRequest.serialize,
response_deserializer=instance.Cluster.deserialize,
@@ -521,7 +621,7 @@ def list_clusters(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "list_clusters" not in self._stubs:
- self._stubs["list_clusters"] = self.grpc_channel.unary_unary(
+ self._stubs["list_clusters"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/ListClusters",
request_serializer=bigtable_instance_admin.ListClustersRequest.serialize,
response_deserializer=bigtable_instance_admin.ListClustersResponse.deserialize,
@@ -551,7 +651,7 @@ def update_cluster(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "update_cluster" not in self._stubs:
- self._stubs["update_cluster"] = self.grpc_channel.unary_unary(
+ self._stubs["update_cluster"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/UpdateCluster",
request_serializer=instance.Cluster.serialize,
response_deserializer=operations_pb2.Operation.FromString,
@@ -593,7 +693,7 @@ def partial_update_cluster(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "partial_update_cluster" not in self._stubs:
- self._stubs["partial_update_cluster"] = self.grpc_channel.unary_unary(
+ self._stubs["partial_update_cluster"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/PartialUpdateCluster",
request_serializer=bigtable_instance_admin.PartialUpdateClusterRequest.serialize,
response_deserializer=operations_pb2.Operation.FromString,
@@ -621,7 +721,7 @@ def delete_cluster(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "delete_cluster" not in self._stubs:
- self._stubs["delete_cluster"] = self.grpc_channel.unary_unary(
+ self._stubs["delete_cluster"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/DeleteCluster",
request_serializer=bigtable_instance_admin.DeleteClusterRequest.serialize,
response_deserializer=empty_pb2.Empty.FromString,
@@ -650,7 +750,7 @@ def create_app_profile(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "create_app_profile" not in self._stubs:
- self._stubs["create_app_profile"] = self.grpc_channel.unary_unary(
+ self._stubs["create_app_profile"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/CreateAppProfile",
request_serializer=bigtable_instance_admin.CreateAppProfileRequest.serialize,
response_deserializer=instance.AppProfile.deserialize,
@@ -678,7 +778,7 @@ def get_app_profile(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "get_app_profile" not in self._stubs:
- self._stubs["get_app_profile"] = self.grpc_channel.unary_unary(
+ self._stubs["get_app_profile"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/GetAppProfile",
request_serializer=bigtable_instance_admin.GetAppProfileRequest.serialize,
response_deserializer=instance.AppProfile.deserialize,
@@ -707,7 +807,7 @@ def list_app_profiles(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "list_app_profiles" not in self._stubs:
- self._stubs["list_app_profiles"] = self.grpc_channel.unary_unary(
+ self._stubs["list_app_profiles"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/ListAppProfiles",
request_serializer=bigtable_instance_admin.ListAppProfilesRequest.serialize,
response_deserializer=bigtable_instance_admin.ListAppProfilesResponse.deserialize,
@@ -736,7 +836,7 @@ def update_app_profile(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "update_app_profile" not in self._stubs:
- self._stubs["update_app_profile"] = self.grpc_channel.unary_unary(
+ self._stubs["update_app_profile"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/UpdateAppProfile",
request_serializer=bigtable_instance_admin.UpdateAppProfileRequest.serialize,
response_deserializer=operations_pb2.Operation.FromString,
@@ -764,7 +864,7 @@ def delete_app_profile(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "delete_app_profile" not in self._stubs:
- self._stubs["delete_app_profile"] = self.grpc_channel.unary_unary(
+ self._stubs["delete_app_profile"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/DeleteAppProfile",
request_serializer=bigtable_instance_admin.DeleteAppProfileRequest.serialize,
response_deserializer=empty_pb2.Empty.FromString,
@@ -792,7 +892,7 @@ def get_iam_policy(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "get_iam_policy" not in self._stubs:
- self._stubs["get_iam_policy"] = self.grpc_channel.unary_unary(
+ self._stubs["get_iam_policy"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/GetIamPolicy",
request_serializer=iam_policy_pb2.GetIamPolicyRequest.SerializeToString,
response_deserializer=policy_pb2.Policy.FromString,
@@ -819,7 +919,7 @@ def set_iam_policy(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "set_iam_policy" not in self._stubs:
- self._stubs["set_iam_policy"] = self.grpc_channel.unary_unary(
+ self._stubs["set_iam_policy"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/SetIamPolicy",
request_serializer=iam_policy_pb2.SetIamPolicyRequest.SerializeToString,
response_deserializer=policy_pb2.Policy.FromString,
@@ -849,7 +949,7 @@ def test_iam_permissions(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "test_iam_permissions" not in self._stubs:
- self._stubs["test_iam_permissions"] = self.grpc_channel.unary_unary(
+ self._stubs["test_iam_permissions"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/TestIamPermissions",
request_serializer=iam_policy_pb2.TestIamPermissionsRequest.SerializeToString,
response_deserializer=iam_policy_pb2.TestIamPermissionsResponse.FromString,
@@ -879,15 +979,603 @@ def list_hot_tablets(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "list_hot_tablets" not in self._stubs:
- self._stubs["list_hot_tablets"] = self.grpc_channel.unary_unary(
+ self._stubs["list_hot_tablets"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableInstanceAdmin/ListHotTablets",
request_serializer=bigtable_instance_admin.ListHotTabletsRequest.serialize,
response_deserializer=bigtable_instance_admin.ListHotTabletsResponse.deserialize,
)
return self._stubs["list_hot_tablets"]
+ @property
+ def create_logical_view(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.CreateLogicalViewRequest],
+ Awaitable[operations_pb2.Operation],
+ ]:
+ r"""Return a callable for the create logical view method over gRPC.
+
+ Creates a logical view within an instance.
+
+ Returns:
+ Callable[[~.CreateLogicalViewRequest],
+ Awaitable[~.Operation]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "create_logical_view" not in self._stubs:
+ self._stubs["create_logical_view"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableInstanceAdmin/CreateLogicalView",
+ request_serializer=bigtable_instance_admin.CreateLogicalViewRequest.serialize,
+ response_deserializer=operations_pb2.Operation.FromString,
+ )
+ return self._stubs["create_logical_view"]
+
+ @property
+ def get_logical_view(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.GetLogicalViewRequest], Awaitable[instance.LogicalView]
+ ]:
+ r"""Return a callable for the get logical view method over gRPC.
+
+ Gets information about a logical view.
+
+ Returns:
+ Callable[[~.GetLogicalViewRequest],
+ Awaitable[~.LogicalView]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "get_logical_view" not in self._stubs:
+ self._stubs["get_logical_view"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableInstanceAdmin/GetLogicalView",
+ request_serializer=bigtable_instance_admin.GetLogicalViewRequest.serialize,
+ response_deserializer=instance.LogicalView.deserialize,
+ )
+ return self._stubs["get_logical_view"]
+
+ @property
+ def list_logical_views(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.ListLogicalViewsRequest],
+ Awaitable[bigtable_instance_admin.ListLogicalViewsResponse],
+ ]:
+ r"""Return a callable for the list logical views method over gRPC.
+
+ Lists information about logical views in an instance.
+
+ Returns:
+ Callable[[~.ListLogicalViewsRequest],
+ Awaitable[~.ListLogicalViewsResponse]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "list_logical_views" not in self._stubs:
+ self._stubs["list_logical_views"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableInstanceAdmin/ListLogicalViews",
+ request_serializer=bigtable_instance_admin.ListLogicalViewsRequest.serialize,
+ response_deserializer=bigtable_instance_admin.ListLogicalViewsResponse.deserialize,
+ )
+ return self._stubs["list_logical_views"]
+
+ @property
+ def update_logical_view(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.UpdateLogicalViewRequest],
+ Awaitable[operations_pb2.Operation],
+ ]:
+ r"""Return a callable for the update logical view method over gRPC.
+
+ Updates a logical view within an instance.
+
+ Returns:
+ Callable[[~.UpdateLogicalViewRequest],
+ Awaitable[~.Operation]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "update_logical_view" not in self._stubs:
+ self._stubs["update_logical_view"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableInstanceAdmin/UpdateLogicalView",
+ request_serializer=bigtable_instance_admin.UpdateLogicalViewRequest.serialize,
+ response_deserializer=operations_pb2.Operation.FromString,
+ )
+ return self._stubs["update_logical_view"]
+
+ @property
+ def delete_logical_view(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.DeleteLogicalViewRequest], Awaitable[empty_pb2.Empty]
+ ]:
+ r"""Return a callable for the delete logical view method over gRPC.
+
+ Deletes a logical view from an instance.
+
+ Returns:
+ Callable[[~.DeleteLogicalViewRequest],
+ Awaitable[~.Empty]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "delete_logical_view" not in self._stubs:
+ self._stubs["delete_logical_view"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableInstanceAdmin/DeleteLogicalView",
+ request_serializer=bigtable_instance_admin.DeleteLogicalViewRequest.serialize,
+ response_deserializer=empty_pb2.Empty.FromString,
+ )
+ return self._stubs["delete_logical_view"]
+
+ @property
+ def create_materialized_view(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.CreateMaterializedViewRequest],
+ Awaitable[operations_pb2.Operation],
+ ]:
+ r"""Return a callable for the create materialized view method over gRPC.
+
+ Creates a materialized view within an instance.
+
+ Returns:
+ Callable[[~.CreateMaterializedViewRequest],
+ Awaitable[~.Operation]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "create_materialized_view" not in self._stubs:
+ self._stubs["create_materialized_view"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableInstanceAdmin/CreateMaterializedView",
+ request_serializer=bigtable_instance_admin.CreateMaterializedViewRequest.serialize,
+ response_deserializer=operations_pb2.Operation.FromString,
+ )
+ return self._stubs["create_materialized_view"]
+
+ @property
+ def get_materialized_view(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.GetMaterializedViewRequest],
+ Awaitable[instance.MaterializedView],
+ ]:
+ r"""Return a callable for the get materialized view method over gRPC.
+
+ Gets information about a materialized view.
+
+ Returns:
+ Callable[[~.GetMaterializedViewRequest],
+ Awaitable[~.MaterializedView]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "get_materialized_view" not in self._stubs:
+ self._stubs["get_materialized_view"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableInstanceAdmin/GetMaterializedView",
+ request_serializer=bigtable_instance_admin.GetMaterializedViewRequest.serialize,
+ response_deserializer=instance.MaterializedView.deserialize,
+ )
+ return self._stubs["get_materialized_view"]
+
+ @property
+ def list_materialized_views(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.ListMaterializedViewsRequest],
+ Awaitable[bigtable_instance_admin.ListMaterializedViewsResponse],
+ ]:
+ r"""Return a callable for the list materialized views method over gRPC.
+
+ Lists information about materialized views in an
+ instance.
+
+ Returns:
+ Callable[[~.ListMaterializedViewsRequest],
+ Awaitable[~.ListMaterializedViewsResponse]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "list_materialized_views" not in self._stubs:
+ self._stubs["list_materialized_views"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableInstanceAdmin/ListMaterializedViews",
+ request_serializer=bigtable_instance_admin.ListMaterializedViewsRequest.serialize,
+ response_deserializer=bigtable_instance_admin.ListMaterializedViewsResponse.deserialize,
+ )
+ return self._stubs["list_materialized_views"]
+
+ @property
+ def update_materialized_view(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.UpdateMaterializedViewRequest],
+ Awaitable[operations_pb2.Operation],
+ ]:
+ r"""Return a callable for the update materialized view method over gRPC.
+
+ Updates a materialized view within an instance.
+
+ Returns:
+ Callable[[~.UpdateMaterializedViewRequest],
+ Awaitable[~.Operation]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "update_materialized_view" not in self._stubs:
+ self._stubs["update_materialized_view"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableInstanceAdmin/UpdateMaterializedView",
+ request_serializer=bigtable_instance_admin.UpdateMaterializedViewRequest.serialize,
+ response_deserializer=operations_pb2.Operation.FromString,
+ )
+ return self._stubs["update_materialized_view"]
+
+ @property
+ def delete_materialized_view(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.DeleteMaterializedViewRequest],
+ Awaitable[empty_pb2.Empty],
+ ]:
+ r"""Return a callable for the delete materialized view method over gRPC.
+
+ Deletes a materialized view from an instance.
+
+ Returns:
+ Callable[[~.DeleteMaterializedViewRequest],
+ Awaitable[~.Empty]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "delete_materialized_view" not in self._stubs:
+ self._stubs["delete_materialized_view"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableInstanceAdmin/DeleteMaterializedView",
+ request_serializer=bigtable_instance_admin.DeleteMaterializedViewRequest.serialize,
+ response_deserializer=empty_pb2.Empty.FromString,
+ )
+ return self._stubs["delete_materialized_view"]
+
+ def _prep_wrapped_messages(self, client_info):
+ """Precompute the wrapped methods, overriding the base class method to use async wrappers."""
+ self._wrapped_methods = {
+ self.create_instance: self._wrap_method(
+ self.create_instance,
+ default_timeout=300.0,
+ client_info=client_info,
+ ),
+ self.get_instance: self._wrap_method(
+ self.get_instance,
+ default_retry=retries.AsyncRetry(
+ initial=1.0,
+ maximum=60.0,
+ multiplier=2,
+ predicate=retries.if_exception_type(
+ core_exceptions.DeadlineExceeded,
+ core_exceptions.ServiceUnavailable,
+ ),
+ deadline=60.0,
+ ),
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.list_instances: self._wrap_method(
+ self.list_instances,
+ default_retry=retries.AsyncRetry(
+ initial=1.0,
+ maximum=60.0,
+ multiplier=2,
+ predicate=retries.if_exception_type(
+ core_exceptions.DeadlineExceeded,
+ core_exceptions.ServiceUnavailable,
+ ),
+ deadline=60.0,
+ ),
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.update_instance: self._wrap_method(
+ self.update_instance,
+ default_retry=retries.AsyncRetry(
+ initial=1.0,
+ maximum=60.0,
+ multiplier=2,
+ predicate=retries.if_exception_type(
+ core_exceptions.DeadlineExceeded,
+ core_exceptions.ServiceUnavailable,
+ ),
+ deadline=60.0,
+ ),
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.partial_update_instance: self._wrap_method(
+ self.partial_update_instance,
+ default_retry=retries.AsyncRetry(
+ initial=1.0,
+ maximum=60.0,
+ multiplier=2,
+ predicate=retries.if_exception_type(
+ core_exceptions.DeadlineExceeded,
+ core_exceptions.ServiceUnavailable,
+ ),
+ deadline=60.0,
+ ),
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.delete_instance: self._wrap_method(
+ self.delete_instance,
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.create_cluster: self._wrap_method(
+ self.create_cluster,
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.get_cluster: self._wrap_method(
+ self.get_cluster,
+ default_retry=retries.AsyncRetry(
+ initial=1.0,
+ maximum=60.0,
+ multiplier=2,
+ predicate=retries.if_exception_type(
+ core_exceptions.DeadlineExceeded,
+ core_exceptions.ServiceUnavailable,
+ ),
+ deadline=60.0,
+ ),
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.list_clusters: self._wrap_method(
+ self.list_clusters,
+ default_retry=retries.AsyncRetry(
+ initial=1.0,
+ maximum=60.0,
+ multiplier=2,
+ predicate=retries.if_exception_type(
+ core_exceptions.DeadlineExceeded,
+ core_exceptions.ServiceUnavailable,
+ ),
+ deadline=60.0,
+ ),
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.update_cluster: self._wrap_method(
+ self.update_cluster,
+ default_retry=retries.AsyncRetry(
+ initial=1.0,
+ maximum=60.0,
+ multiplier=2,
+ predicate=retries.if_exception_type(
+ core_exceptions.DeadlineExceeded,
+ core_exceptions.ServiceUnavailable,
+ ),
+ deadline=60.0,
+ ),
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.partial_update_cluster: self._wrap_method(
+ self.partial_update_cluster,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.delete_cluster: self._wrap_method(
+ self.delete_cluster,
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.create_app_profile: self._wrap_method(
+ self.create_app_profile,
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.get_app_profile: self._wrap_method(
+ self.get_app_profile,
+ default_retry=retries.AsyncRetry(
+ initial=1.0,
+ maximum=60.0,
+ multiplier=2,
+ predicate=retries.if_exception_type(
+ core_exceptions.DeadlineExceeded,
+ core_exceptions.ServiceUnavailable,
+ ),
+ deadline=60.0,
+ ),
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.list_app_profiles: self._wrap_method(
+ self.list_app_profiles,
+ default_retry=retries.AsyncRetry(
+ initial=1.0,
+ maximum=60.0,
+ multiplier=2,
+ predicate=retries.if_exception_type(
+ core_exceptions.DeadlineExceeded,
+ core_exceptions.ServiceUnavailable,
+ ),
+ deadline=60.0,
+ ),
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.update_app_profile: self._wrap_method(
+ self.update_app_profile,
+ default_retry=retries.AsyncRetry(
+ initial=1.0,
+ maximum=60.0,
+ multiplier=2,
+ predicate=retries.if_exception_type(
+ core_exceptions.DeadlineExceeded,
+ core_exceptions.ServiceUnavailable,
+ ),
+ deadline=60.0,
+ ),
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.delete_app_profile: self._wrap_method(
+ self.delete_app_profile,
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.get_iam_policy: self._wrap_method(
+ self.get_iam_policy,
+ default_retry=retries.AsyncRetry(
+ initial=1.0,
+ maximum=60.0,
+ multiplier=2,
+ predicate=retries.if_exception_type(
+ core_exceptions.DeadlineExceeded,
+ core_exceptions.ServiceUnavailable,
+ ),
+ deadline=60.0,
+ ),
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.set_iam_policy: self._wrap_method(
+ self.set_iam_policy,
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.test_iam_permissions: self._wrap_method(
+ self.test_iam_permissions,
+ default_retry=retries.AsyncRetry(
+ initial=1.0,
+ maximum=60.0,
+ multiplier=2,
+ predicate=retries.if_exception_type(
+ core_exceptions.DeadlineExceeded,
+ core_exceptions.ServiceUnavailable,
+ ),
+ deadline=60.0,
+ ),
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.list_hot_tablets: self._wrap_method(
+ self.list_hot_tablets,
+ default_retry=retries.AsyncRetry(
+ initial=1.0,
+ maximum=60.0,
+ multiplier=2,
+ predicate=retries.if_exception_type(
+ core_exceptions.DeadlineExceeded,
+ core_exceptions.ServiceUnavailable,
+ ),
+ deadline=60.0,
+ ),
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.create_logical_view: self._wrap_method(
+ self.create_logical_view,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.get_logical_view: self._wrap_method(
+ self.get_logical_view,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.list_logical_views: self._wrap_method(
+ self.list_logical_views,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.update_logical_view: self._wrap_method(
+ self.update_logical_view,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.delete_logical_view: self._wrap_method(
+ self.delete_logical_view,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.create_materialized_view: self._wrap_method(
+ self.create_materialized_view,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.get_materialized_view: self._wrap_method(
+ self.get_materialized_view,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.list_materialized_views: self._wrap_method(
+ self.list_materialized_views,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.update_materialized_view: self._wrap_method(
+ self.update_materialized_view,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.delete_materialized_view: self._wrap_method(
+ self.delete_materialized_view,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ }
+
+ def _wrap_method(self, func, *args, **kwargs):
+ if self._wrap_with_kind: # pragma: NO COVER
+ kwargs["kind"] = self.kind
+ return gapic_v1.method_async.wrap_method(func, *args, **kwargs)
+
def close(self):
- return self.grpc_channel.close()
+ return self._logged_channel.close()
+
+ @property
+ def kind(self) -> str:
+ return "grpc_asyncio"
__all__ = ("BigtableInstanceAdminGrpcAsyncIOTransport",)
diff --git a/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/rest.py b/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/rest.py
new file mode 100644
index 000000000..9879c4c45
--- /dev/null
+++ b/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/rest.py
@@ -0,0 +1,6825 @@
+# -*- coding: utf-8 -*-
+# Copyright 2025 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 logging
+import json # type: ignore
+
+from google.auth.transport.requests import AuthorizedSession # type: ignore
+from google.auth import credentials as ga_credentials # type: ignore
+from google.api_core import exceptions as core_exceptions
+from google.api_core import retry as retries
+from google.api_core import rest_helpers
+from google.api_core import rest_streaming
+from google.api_core import gapic_v1
+import google.protobuf
+
+from google.protobuf import json_format
+from google.api_core import operations_v1
+
+from requests import __version__ as requests_version
+import dataclasses
+from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union
+import warnings
+
+
+from google.cloud.bigtable_admin_v2.types import bigtable_instance_admin
+from google.cloud.bigtable_admin_v2.types import instance
+from google.iam.v1 import iam_policy_pb2 # type: ignore
+from google.iam.v1 import policy_pb2 # type: ignore
+from google.protobuf import empty_pb2 # type: ignore
+from google.longrunning import operations_pb2 # type: ignore
+
+
+from .rest_base import _BaseBigtableInstanceAdminRestTransport
+from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO
+
+try:
+ OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None]
+except AttributeError: # pragma: NO COVER
+ OptionalRetry = Union[retries.Retry, object, None] # type: ignore
+
+try:
+ from google.api_core import client_logging # type: ignore
+
+ CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER
+except ImportError: # pragma: NO COVER
+ CLIENT_LOGGING_SUPPORTED = False
+
+_LOGGER = logging.getLogger(__name__)
+
+DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
+ gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version,
+ grpc_version=None,
+ rest_version=f"requests@{requests_version}",
+)
+
+if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER
+ DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__
+
+
+class BigtableInstanceAdminRestInterceptor:
+ """Interceptor for BigtableInstanceAdmin.
+
+ Interceptors are used to manipulate requests, request metadata, and responses
+ in arbitrary ways.
+ Example use cases include:
+ * Logging
+ * Verifying requests according to service or custom semantics
+ * Stripping extraneous information from responses
+
+ These use cases and more can be enabled by injecting an
+ instance of a custom subclass when constructing the BigtableInstanceAdminRestTransport.
+
+ .. code-block:: python
+ class MyCustomBigtableInstanceAdminInterceptor(BigtableInstanceAdminRestInterceptor):
+ def pre_create_app_profile(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_create_app_profile(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_create_cluster(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_create_cluster(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_create_instance(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_create_instance(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_create_logical_view(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_create_logical_view(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_create_materialized_view(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_create_materialized_view(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_delete_app_profile(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def pre_delete_cluster(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def pre_delete_instance(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def pre_delete_logical_view(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def pre_delete_materialized_view(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def pre_get_app_profile(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_get_app_profile(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_get_cluster(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_get_cluster(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_get_iam_policy(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_get_iam_policy(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_get_instance(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_get_instance(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_get_logical_view(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_get_logical_view(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_get_materialized_view(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_get_materialized_view(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_list_app_profiles(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_list_app_profiles(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_list_clusters(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_list_clusters(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_list_hot_tablets(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_list_hot_tablets(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_list_instances(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_list_instances(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_list_logical_views(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_list_logical_views(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_list_materialized_views(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_list_materialized_views(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_partial_update_cluster(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_partial_update_cluster(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_partial_update_instance(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_partial_update_instance(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_set_iam_policy(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_set_iam_policy(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_test_iam_permissions(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_test_iam_permissions(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_update_app_profile(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_update_app_profile(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_update_cluster(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_update_cluster(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_update_instance(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_update_instance(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_update_logical_view(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_update_logical_view(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_update_materialized_view(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_update_materialized_view(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ transport = BigtableInstanceAdminRestTransport(interceptor=MyCustomBigtableInstanceAdminInterceptor())
+ client = BigtableInstanceAdminClient(transport=transport)
+
+
+ """
+
+ def pre_create_app_profile(
+ self,
+ request: bigtable_instance_admin.CreateAppProfileRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.CreateAppProfileRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for create_app_profile
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def post_create_app_profile(
+ self, response: instance.AppProfile
+ ) -> instance.AppProfile:
+ """Post-rpc interceptor for create_app_profile
+
+ DEPRECATED. Please use the `post_create_app_profile_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableInstanceAdmin server but before
+ it is returned to user code. This `post_create_app_profile` interceptor runs
+ before the `post_create_app_profile_with_metadata` interceptor.
+ """
+ return response
+
+ def post_create_app_profile_with_metadata(
+ self,
+ response: instance.AppProfile,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[instance.AppProfile, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for create_app_profile
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableInstanceAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_create_app_profile_with_metadata`
+ interceptor in new development instead of the `post_create_app_profile` interceptor.
+ When both interceptors are used, this `post_create_app_profile_with_metadata` interceptor runs after the
+ `post_create_app_profile` interceptor. The (possibly modified) response returned by
+ `post_create_app_profile` will be passed to
+ `post_create_app_profile_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_create_cluster(
+ self,
+ request: bigtable_instance_admin.CreateClusterRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.CreateClusterRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for create_cluster
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def post_create_cluster(
+ self, response: operations_pb2.Operation
+ ) -> operations_pb2.Operation:
+ """Post-rpc interceptor for create_cluster
+
+ DEPRECATED. Please use the `post_create_cluster_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableInstanceAdmin server but before
+ it is returned to user code. This `post_create_cluster` interceptor runs
+ before the `post_create_cluster_with_metadata` interceptor.
+ """
+ return response
+
+ def post_create_cluster_with_metadata(
+ self,
+ response: operations_pb2.Operation,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for create_cluster
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableInstanceAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_create_cluster_with_metadata`
+ interceptor in new development instead of the `post_create_cluster` interceptor.
+ When both interceptors are used, this `post_create_cluster_with_metadata` interceptor runs after the
+ `post_create_cluster` interceptor. The (possibly modified) response returned by
+ `post_create_cluster` will be passed to
+ `post_create_cluster_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_create_instance(
+ self,
+ request: bigtable_instance_admin.CreateInstanceRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.CreateInstanceRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for create_instance
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def post_create_instance(
+ self, response: operations_pb2.Operation
+ ) -> operations_pb2.Operation:
+ """Post-rpc interceptor for create_instance
+
+ DEPRECATED. Please use the `post_create_instance_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableInstanceAdmin server but before
+ it is returned to user code. This `post_create_instance` interceptor runs
+ before the `post_create_instance_with_metadata` interceptor.
+ """
+ return response
+
+ def post_create_instance_with_metadata(
+ self,
+ response: operations_pb2.Operation,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for create_instance
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableInstanceAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_create_instance_with_metadata`
+ interceptor in new development instead of the `post_create_instance` interceptor.
+ When both interceptors are used, this `post_create_instance_with_metadata` interceptor runs after the
+ `post_create_instance` interceptor. The (possibly modified) response returned by
+ `post_create_instance` will be passed to
+ `post_create_instance_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_create_logical_view(
+ self,
+ request: bigtable_instance_admin.CreateLogicalViewRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.CreateLogicalViewRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for create_logical_view
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def post_create_logical_view(
+ self, response: operations_pb2.Operation
+ ) -> operations_pb2.Operation:
+ """Post-rpc interceptor for create_logical_view
+
+ DEPRECATED. Please use the `post_create_logical_view_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableInstanceAdmin server but before
+ it is returned to user code. This `post_create_logical_view` interceptor runs
+ before the `post_create_logical_view_with_metadata` interceptor.
+ """
+ return response
+
+ def post_create_logical_view_with_metadata(
+ self,
+ response: operations_pb2.Operation,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for create_logical_view
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableInstanceAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_create_logical_view_with_metadata`
+ interceptor in new development instead of the `post_create_logical_view` interceptor.
+ When both interceptors are used, this `post_create_logical_view_with_metadata` interceptor runs after the
+ `post_create_logical_view` interceptor. The (possibly modified) response returned by
+ `post_create_logical_view` will be passed to
+ `post_create_logical_view_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_create_materialized_view(
+ self,
+ request: bigtable_instance_admin.CreateMaterializedViewRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.CreateMaterializedViewRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for create_materialized_view
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def post_create_materialized_view(
+ self, response: operations_pb2.Operation
+ ) -> operations_pb2.Operation:
+ """Post-rpc interceptor for create_materialized_view
+
+ DEPRECATED. Please use the `post_create_materialized_view_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableInstanceAdmin server but before
+ it is returned to user code. This `post_create_materialized_view` interceptor runs
+ before the `post_create_materialized_view_with_metadata` interceptor.
+ """
+ return response
+
+ def post_create_materialized_view_with_metadata(
+ self,
+ response: operations_pb2.Operation,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for create_materialized_view
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableInstanceAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_create_materialized_view_with_metadata`
+ interceptor in new development instead of the `post_create_materialized_view` interceptor.
+ When both interceptors are used, this `post_create_materialized_view_with_metadata` interceptor runs after the
+ `post_create_materialized_view` interceptor. The (possibly modified) response returned by
+ `post_create_materialized_view` will be passed to
+ `post_create_materialized_view_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_delete_app_profile(
+ self,
+ request: bigtable_instance_admin.DeleteAppProfileRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.DeleteAppProfileRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for delete_app_profile
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def pre_delete_cluster(
+ self,
+ request: bigtable_instance_admin.DeleteClusterRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.DeleteClusterRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for delete_cluster
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def pre_delete_instance(
+ self,
+ request: bigtable_instance_admin.DeleteInstanceRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.DeleteInstanceRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for delete_instance
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def pre_delete_logical_view(
+ self,
+ request: bigtable_instance_admin.DeleteLogicalViewRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.DeleteLogicalViewRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for delete_logical_view
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def pre_delete_materialized_view(
+ self,
+ request: bigtable_instance_admin.DeleteMaterializedViewRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.DeleteMaterializedViewRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for delete_materialized_view
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def pre_get_app_profile(
+ self,
+ request: bigtable_instance_admin.GetAppProfileRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.GetAppProfileRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for get_app_profile
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def post_get_app_profile(
+ self, response: instance.AppProfile
+ ) -> instance.AppProfile:
+ """Post-rpc interceptor for get_app_profile
+
+ DEPRECATED. Please use the `post_get_app_profile_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableInstanceAdmin server but before
+ it is returned to user code. This `post_get_app_profile` interceptor runs
+ before the `post_get_app_profile_with_metadata` interceptor.
+ """
+ return response
+
+ def post_get_app_profile_with_metadata(
+ self,
+ response: instance.AppProfile,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[instance.AppProfile, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for get_app_profile
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableInstanceAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_get_app_profile_with_metadata`
+ interceptor in new development instead of the `post_get_app_profile` interceptor.
+ When both interceptors are used, this `post_get_app_profile_with_metadata` interceptor runs after the
+ `post_get_app_profile` interceptor. The (possibly modified) response returned by
+ `post_get_app_profile` will be passed to
+ `post_get_app_profile_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_get_cluster(
+ self,
+ request: bigtable_instance_admin.GetClusterRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.GetClusterRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for get_cluster
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def post_get_cluster(self, response: instance.Cluster) -> instance.Cluster:
+ """Post-rpc interceptor for get_cluster
+
+ DEPRECATED. Please use the `post_get_cluster_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableInstanceAdmin server but before
+ it is returned to user code. This `post_get_cluster` interceptor runs
+ before the `post_get_cluster_with_metadata` interceptor.
+ """
+ return response
+
+ def post_get_cluster_with_metadata(
+ self,
+ response: instance.Cluster,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[instance.Cluster, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for get_cluster
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableInstanceAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_get_cluster_with_metadata`
+ interceptor in new development instead of the `post_get_cluster` interceptor.
+ When both interceptors are used, this `post_get_cluster_with_metadata` interceptor runs after the
+ `post_get_cluster` interceptor. The (possibly modified) response returned by
+ `post_get_cluster` will be passed to
+ `post_get_cluster_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_get_iam_policy(
+ self,
+ request: iam_policy_pb2.GetIamPolicyRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ iam_policy_pb2.GetIamPolicyRequest, Sequence[Tuple[str, Union[str, bytes]]]
+ ]:
+ """Pre-rpc interceptor for get_iam_policy
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def post_get_iam_policy(self, response: policy_pb2.Policy) -> policy_pb2.Policy:
+ """Post-rpc interceptor for get_iam_policy
+
+ DEPRECATED. Please use the `post_get_iam_policy_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableInstanceAdmin server but before
+ it is returned to user code. This `post_get_iam_policy` interceptor runs
+ before the `post_get_iam_policy_with_metadata` interceptor.
+ """
+ return response
+
+ def post_get_iam_policy_with_metadata(
+ self,
+ response: policy_pb2.Policy,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[policy_pb2.Policy, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for get_iam_policy
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableInstanceAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_get_iam_policy_with_metadata`
+ interceptor in new development instead of the `post_get_iam_policy` interceptor.
+ When both interceptors are used, this `post_get_iam_policy_with_metadata` interceptor runs after the
+ `post_get_iam_policy` interceptor. The (possibly modified) response returned by
+ `post_get_iam_policy` will be passed to
+ `post_get_iam_policy_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_get_instance(
+ self,
+ request: bigtable_instance_admin.GetInstanceRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.GetInstanceRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for get_instance
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def post_get_instance(self, response: instance.Instance) -> instance.Instance:
+ """Post-rpc interceptor for get_instance
+
+ DEPRECATED. Please use the `post_get_instance_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableInstanceAdmin server but before
+ it is returned to user code. This `post_get_instance` interceptor runs
+ before the `post_get_instance_with_metadata` interceptor.
+ """
+ return response
+
+ def post_get_instance_with_metadata(
+ self,
+ response: instance.Instance,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[instance.Instance, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for get_instance
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableInstanceAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_get_instance_with_metadata`
+ interceptor in new development instead of the `post_get_instance` interceptor.
+ When both interceptors are used, this `post_get_instance_with_metadata` interceptor runs after the
+ `post_get_instance` interceptor. The (possibly modified) response returned by
+ `post_get_instance` will be passed to
+ `post_get_instance_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_get_logical_view(
+ self,
+ request: bigtable_instance_admin.GetLogicalViewRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.GetLogicalViewRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for get_logical_view
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def post_get_logical_view(
+ self, response: instance.LogicalView
+ ) -> instance.LogicalView:
+ """Post-rpc interceptor for get_logical_view
+
+ DEPRECATED. Please use the `post_get_logical_view_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableInstanceAdmin server but before
+ it is returned to user code. This `post_get_logical_view` interceptor runs
+ before the `post_get_logical_view_with_metadata` interceptor.
+ """
+ return response
+
+ def post_get_logical_view_with_metadata(
+ self,
+ response: instance.LogicalView,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[instance.LogicalView, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for get_logical_view
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableInstanceAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_get_logical_view_with_metadata`
+ interceptor in new development instead of the `post_get_logical_view` interceptor.
+ When both interceptors are used, this `post_get_logical_view_with_metadata` interceptor runs after the
+ `post_get_logical_view` interceptor. The (possibly modified) response returned by
+ `post_get_logical_view` will be passed to
+ `post_get_logical_view_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_get_materialized_view(
+ self,
+ request: bigtable_instance_admin.GetMaterializedViewRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.GetMaterializedViewRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for get_materialized_view
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def post_get_materialized_view(
+ self, response: instance.MaterializedView
+ ) -> instance.MaterializedView:
+ """Post-rpc interceptor for get_materialized_view
+
+ DEPRECATED. Please use the `post_get_materialized_view_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableInstanceAdmin server but before
+ it is returned to user code. This `post_get_materialized_view` interceptor runs
+ before the `post_get_materialized_view_with_metadata` interceptor.
+ """
+ return response
+
+ def post_get_materialized_view_with_metadata(
+ self,
+ response: instance.MaterializedView,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[instance.MaterializedView, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for get_materialized_view
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableInstanceAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_get_materialized_view_with_metadata`
+ interceptor in new development instead of the `post_get_materialized_view` interceptor.
+ When both interceptors are used, this `post_get_materialized_view_with_metadata` interceptor runs after the
+ `post_get_materialized_view` interceptor. The (possibly modified) response returned by
+ `post_get_materialized_view` will be passed to
+ `post_get_materialized_view_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_list_app_profiles(
+ self,
+ request: bigtable_instance_admin.ListAppProfilesRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.ListAppProfilesRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for list_app_profiles
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def post_list_app_profiles(
+ self, response: bigtable_instance_admin.ListAppProfilesResponse
+ ) -> bigtable_instance_admin.ListAppProfilesResponse:
+ """Post-rpc interceptor for list_app_profiles
+
+ DEPRECATED. Please use the `post_list_app_profiles_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableInstanceAdmin server but before
+ it is returned to user code. This `post_list_app_profiles` interceptor runs
+ before the `post_list_app_profiles_with_metadata` interceptor.
+ """
+ return response
+
+ def post_list_app_profiles_with_metadata(
+ self,
+ response: bigtable_instance_admin.ListAppProfilesResponse,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.ListAppProfilesResponse,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Post-rpc interceptor for list_app_profiles
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableInstanceAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_list_app_profiles_with_metadata`
+ interceptor in new development instead of the `post_list_app_profiles` interceptor.
+ When both interceptors are used, this `post_list_app_profiles_with_metadata` interceptor runs after the
+ `post_list_app_profiles` interceptor. The (possibly modified) response returned by
+ `post_list_app_profiles` will be passed to
+ `post_list_app_profiles_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_list_clusters(
+ self,
+ request: bigtable_instance_admin.ListClustersRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.ListClustersRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for list_clusters
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def post_list_clusters(
+ self, response: bigtable_instance_admin.ListClustersResponse
+ ) -> bigtable_instance_admin.ListClustersResponse:
+ """Post-rpc interceptor for list_clusters
+
+ DEPRECATED. Please use the `post_list_clusters_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableInstanceAdmin server but before
+ it is returned to user code. This `post_list_clusters` interceptor runs
+ before the `post_list_clusters_with_metadata` interceptor.
+ """
+ return response
+
+ def post_list_clusters_with_metadata(
+ self,
+ response: bigtable_instance_admin.ListClustersResponse,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.ListClustersResponse,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Post-rpc interceptor for list_clusters
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableInstanceAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_list_clusters_with_metadata`
+ interceptor in new development instead of the `post_list_clusters` interceptor.
+ When both interceptors are used, this `post_list_clusters_with_metadata` interceptor runs after the
+ `post_list_clusters` interceptor. The (possibly modified) response returned by
+ `post_list_clusters` will be passed to
+ `post_list_clusters_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_list_hot_tablets(
+ self,
+ request: bigtable_instance_admin.ListHotTabletsRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.ListHotTabletsRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for list_hot_tablets
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def post_list_hot_tablets(
+ self, response: bigtable_instance_admin.ListHotTabletsResponse
+ ) -> bigtable_instance_admin.ListHotTabletsResponse:
+ """Post-rpc interceptor for list_hot_tablets
+
+ DEPRECATED. Please use the `post_list_hot_tablets_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableInstanceAdmin server but before
+ it is returned to user code. This `post_list_hot_tablets` interceptor runs
+ before the `post_list_hot_tablets_with_metadata` interceptor.
+ """
+ return response
+
+ def post_list_hot_tablets_with_metadata(
+ self,
+ response: bigtable_instance_admin.ListHotTabletsResponse,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.ListHotTabletsResponse,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Post-rpc interceptor for list_hot_tablets
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableInstanceAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_list_hot_tablets_with_metadata`
+ interceptor in new development instead of the `post_list_hot_tablets` interceptor.
+ When both interceptors are used, this `post_list_hot_tablets_with_metadata` interceptor runs after the
+ `post_list_hot_tablets` interceptor. The (possibly modified) response returned by
+ `post_list_hot_tablets` will be passed to
+ `post_list_hot_tablets_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_list_instances(
+ self,
+ request: bigtable_instance_admin.ListInstancesRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.ListInstancesRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for list_instances
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def post_list_instances(
+ self, response: bigtable_instance_admin.ListInstancesResponse
+ ) -> bigtable_instance_admin.ListInstancesResponse:
+ """Post-rpc interceptor for list_instances
+
+ DEPRECATED. Please use the `post_list_instances_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableInstanceAdmin server but before
+ it is returned to user code. This `post_list_instances` interceptor runs
+ before the `post_list_instances_with_metadata` interceptor.
+ """
+ return response
+
+ def post_list_instances_with_metadata(
+ self,
+ response: bigtable_instance_admin.ListInstancesResponse,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.ListInstancesResponse,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Post-rpc interceptor for list_instances
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableInstanceAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_list_instances_with_metadata`
+ interceptor in new development instead of the `post_list_instances` interceptor.
+ When both interceptors are used, this `post_list_instances_with_metadata` interceptor runs after the
+ `post_list_instances` interceptor. The (possibly modified) response returned by
+ `post_list_instances` will be passed to
+ `post_list_instances_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_list_logical_views(
+ self,
+ request: bigtable_instance_admin.ListLogicalViewsRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.ListLogicalViewsRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for list_logical_views
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def post_list_logical_views(
+ self, response: bigtable_instance_admin.ListLogicalViewsResponse
+ ) -> bigtable_instance_admin.ListLogicalViewsResponse:
+ """Post-rpc interceptor for list_logical_views
+
+ DEPRECATED. Please use the `post_list_logical_views_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableInstanceAdmin server but before
+ it is returned to user code. This `post_list_logical_views` interceptor runs
+ before the `post_list_logical_views_with_metadata` interceptor.
+ """
+ return response
+
+ def post_list_logical_views_with_metadata(
+ self,
+ response: bigtable_instance_admin.ListLogicalViewsResponse,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.ListLogicalViewsResponse,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Post-rpc interceptor for list_logical_views
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableInstanceAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_list_logical_views_with_metadata`
+ interceptor in new development instead of the `post_list_logical_views` interceptor.
+ When both interceptors are used, this `post_list_logical_views_with_metadata` interceptor runs after the
+ `post_list_logical_views` interceptor. The (possibly modified) response returned by
+ `post_list_logical_views` will be passed to
+ `post_list_logical_views_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_list_materialized_views(
+ self,
+ request: bigtable_instance_admin.ListMaterializedViewsRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.ListMaterializedViewsRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for list_materialized_views
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def post_list_materialized_views(
+ self, response: bigtable_instance_admin.ListMaterializedViewsResponse
+ ) -> bigtable_instance_admin.ListMaterializedViewsResponse:
+ """Post-rpc interceptor for list_materialized_views
+
+ DEPRECATED. Please use the `post_list_materialized_views_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableInstanceAdmin server but before
+ it is returned to user code. This `post_list_materialized_views` interceptor runs
+ before the `post_list_materialized_views_with_metadata` interceptor.
+ """
+ return response
+
+ def post_list_materialized_views_with_metadata(
+ self,
+ response: bigtable_instance_admin.ListMaterializedViewsResponse,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.ListMaterializedViewsResponse,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Post-rpc interceptor for list_materialized_views
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableInstanceAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_list_materialized_views_with_metadata`
+ interceptor in new development instead of the `post_list_materialized_views` interceptor.
+ When both interceptors are used, this `post_list_materialized_views_with_metadata` interceptor runs after the
+ `post_list_materialized_views` interceptor. The (possibly modified) response returned by
+ `post_list_materialized_views` will be passed to
+ `post_list_materialized_views_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_partial_update_cluster(
+ self,
+ request: bigtable_instance_admin.PartialUpdateClusterRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.PartialUpdateClusterRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for partial_update_cluster
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def post_partial_update_cluster(
+ self, response: operations_pb2.Operation
+ ) -> operations_pb2.Operation:
+ """Post-rpc interceptor for partial_update_cluster
+
+ DEPRECATED. Please use the `post_partial_update_cluster_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableInstanceAdmin server but before
+ it is returned to user code. This `post_partial_update_cluster` interceptor runs
+ before the `post_partial_update_cluster_with_metadata` interceptor.
+ """
+ return response
+
+ def post_partial_update_cluster_with_metadata(
+ self,
+ response: operations_pb2.Operation,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for partial_update_cluster
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableInstanceAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_partial_update_cluster_with_metadata`
+ interceptor in new development instead of the `post_partial_update_cluster` interceptor.
+ When both interceptors are used, this `post_partial_update_cluster_with_metadata` interceptor runs after the
+ `post_partial_update_cluster` interceptor. The (possibly modified) response returned by
+ `post_partial_update_cluster` will be passed to
+ `post_partial_update_cluster_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_partial_update_instance(
+ self,
+ request: bigtable_instance_admin.PartialUpdateInstanceRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.PartialUpdateInstanceRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for partial_update_instance
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def post_partial_update_instance(
+ self, response: operations_pb2.Operation
+ ) -> operations_pb2.Operation:
+ """Post-rpc interceptor for partial_update_instance
+
+ DEPRECATED. Please use the `post_partial_update_instance_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableInstanceAdmin server but before
+ it is returned to user code. This `post_partial_update_instance` interceptor runs
+ before the `post_partial_update_instance_with_metadata` interceptor.
+ """
+ return response
+
+ def post_partial_update_instance_with_metadata(
+ self,
+ response: operations_pb2.Operation,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for partial_update_instance
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableInstanceAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_partial_update_instance_with_metadata`
+ interceptor in new development instead of the `post_partial_update_instance` interceptor.
+ When both interceptors are used, this `post_partial_update_instance_with_metadata` interceptor runs after the
+ `post_partial_update_instance` interceptor. The (possibly modified) response returned by
+ `post_partial_update_instance` will be passed to
+ `post_partial_update_instance_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_set_iam_policy(
+ self,
+ request: iam_policy_pb2.SetIamPolicyRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ iam_policy_pb2.SetIamPolicyRequest, Sequence[Tuple[str, Union[str, bytes]]]
+ ]:
+ """Pre-rpc interceptor for set_iam_policy
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def post_set_iam_policy(self, response: policy_pb2.Policy) -> policy_pb2.Policy:
+ """Post-rpc interceptor for set_iam_policy
+
+ DEPRECATED. Please use the `post_set_iam_policy_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableInstanceAdmin server but before
+ it is returned to user code. This `post_set_iam_policy` interceptor runs
+ before the `post_set_iam_policy_with_metadata` interceptor.
+ """
+ return response
+
+ def post_set_iam_policy_with_metadata(
+ self,
+ response: policy_pb2.Policy,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[policy_pb2.Policy, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for set_iam_policy
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableInstanceAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_set_iam_policy_with_metadata`
+ interceptor in new development instead of the `post_set_iam_policy` interceptor.
+ When both interceptors are used, this `post_set_iam_policy_with_metadata` interceptor runs after the
+ `post_set_iam_policy` interceptor. The (possibly modified) response returned by
+ `post_set_iam_policy` will be passed to
+ `post_set_iam_policy_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_test_iam_permissions(
+ self,
+ request: iam_policy_pb2.TestIamPermissionsRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ iam_policy_pb2.TestIamPermissionsRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for test_iam_permissions
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def post_test_iam_permissions(
+ self, response: iam_policy_pb2.TestIamPermissionsResponse
+ ) -> iam_policy_pb2.TestIamPermissionsResponse:
+ """Post-rpc interceptor for test_iam_permissions
+
+ DEPRECATED. Please use the `post_test_iam_permissions_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableInstanceAdmin server but before
+ it is returned to user code. This `post_test_iam_permissions` interceptor runs
+ before the `post_test_iam_permissions_with_metadata` interceptor.
+ """
+ return response
+
+ def post_test_iam_permissions_with_metadata(
+ self,
+ response: iam_policy_pb2.TestIamPermissionsResponse,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ iam_policy_pb2.TestIamPermissionsResponse,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Post-rpc interceptor for test_iam_permissions
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableInstanceAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_test_iam_permissions_with_metadata`
+ interceptor in new development instead of the `post_test_iam_permissions` interceptor.
+ When both interceptors are used, this `post_test_iam_permissions_with_metadata` interceptor runs after the
+ `post_test_iam_permissions` interceptor. The (possibly modified) response returned by
+ `post_test_iam_permissions` will be passed to
+ `post_test_iam_permissions_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_update_app_profile(
+ self,
+ request: bigtable_instance_admin.UpdateAppProfileRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.UpdateAppProfileRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for update_app_profile
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def post_update_app_profile(
+ self, response: operations_pb2.Operation
+ ) -> operations_pb2.Operation:
+ """Post-rpc interceptor for update_app_profile
+
+ DEPRECATED. Please use the `post_update_app_profile_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableInstanceAdmin server but before
+ it is returned to user code. This `post_update_app_profile` interceptor runs
+ before the `post_update_app_profile_with_metadata` interceptor.
+ """
+ return response
+
+ def post_update_app_profile_with_metadata(
+ self,
+ response: operations_pb2.Operation,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for update_app_profile
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableInstanceAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_update_app_profile_with_metadata`
+ interceptor in new development instead of the `post_update_app_profile` interceptor.
+ When both interceptors are used, this `post_update_app_profile_with_metadata` interceptor runs after the
+ `post_update_app_profile` interceptor. The (possibly modified) response returned by
+ `post_update_app_profile` will be passed to
+ `post_update_app_profile_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_update_cluster(
+ self,
+ request: instance.Cluster,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[instance.Cluster, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Pre-rpc interceptor for update_cluster
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def post_update_cluster(
+ self, response: operations_pb2.Operation
+ ) -> operations_pb2.Operation:
+ """Post-rpc interceptor for update_cluster
+
+ DEPRECATED. Please use the `post_update_cluster_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableInstanceAdmin server but before
+ it is returned to user code. This `post_update_cluster` interceptor runs
+ before the `post_update_cluster_with_metadata` interceptor.
+ """
+ return response
+
+ def post_update_cluster_with_metadata(
+ self,
+ response: operations_pb2.Operation,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for update_cluster
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableInstanceAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_update_cluster_with_metadata`
+ interceptor in new development instead of the `post_update_cluster` interceptor.
+ When both interceptors are used, this `post_update_cluster_with_metadata` interceptor runs after the
+ `post_update_cluster` interceptor. The (possibly modified) response returned by
+ `post_update_cluster` will be passed to
+ `post_update_cluster_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_update_instance(
+ self,
+ request: instance.Instance,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[instance.Instance, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Pre-rpc interceptor for update_instance
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def post_update_instance(self, response: instance.Instance) -> instance.Instance:
+ """Post-rpc interceptor for update_instance
+
+ DEPRECATED. Please use the `post_update_instance_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableInstanceAdmin server but before
+ it is returned to user code. This `post_update_instance` interceptor runs
+ before the `post_update_instance_with_metadata` interceptor.
+ """
+ return response
+
+ def post_update_instance_with_metadata(
+ self,
+ response: instance.Instance,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[instance.Instance, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for update_instance
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableInstanceAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_update_instance_with_metadata`
+ interceptor in new development instead of the `post_update_instance` interceptor.
+ When both interceptors are used, this `post_update_instance_with_metadata` interceptor runs after the
+ `post_update_instance` interceptor. The (possibly modified) response returned by
+ `post_update_instance` will be passed to
+ `post_update_instance_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_update_logical_view(
+ self,
+ request: bigtable_instance_admin.UpdateLogicalViewRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.UpdateLogicalViewRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for update_logical_view
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def post_update_logical_view(
+ self, response: operations_pb2.Operation
+ ) -> operations_pb2.Operation:
+ """Post-rpc interceptor for update_logical_view
+
+ DEPRECATED. Please use the `post_update_logical_view_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableInstanceAdmin server but before
+ it is returned to user code. This `post_update_logical_view` interceptor runs
+ before the `post_update_logical_view_with_metadata` interceptor.
+ """
+ return response
+
+ def post_update_logical_view_with_metadata(
+ self,
+ response: operations_pb2.Operation,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for update_logical_view
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableInstanceAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_update_logical_view_with_metadata`
+ interceptor in new development instead of the `post_update_logical_view` interceptor.
+ When both interceptors are used, this `post_update_logical_view_with_metadata` interceptor runs after the
+ `post_update_logical_view` interceptor. The (possibly modified) response returned by
+ `post_update_logical_view` will be passed to
+ `post_update_logical_view_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_update_materialized_view(
+ self,
+ request: bigtable_instance_admin.UpdateMaterializedViewRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_instance_admin.UpdateMaterializedViewRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for update_materialized_view
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableInstanceAdmin server.
+ """
+ return request, metadata
+
+ def post_update_materialized_view(
+ self, response: operations_pb2.Operation
+ ) -> operations_pb2.Operation:
+ """Post-rpc interceptor for update_materialized_view
+
+ DEPRECATED. Please use the `post_update_materialized_view_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableInstanceAdmin server but before
+ it is returned to user code. This `post_update_materialized_view` interceptor runs
+ before the `post_update_materialized_view_with_metadata` interceptor.
+ """
+ return response
+
+ def post_update_materialized_view_with_metadata(
+ self,
+ response: operations_pb2.Operation,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for update_materialized_view
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableInstanceAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_update_materialized_view_with_metadata`
+ interceptor in new development instead of the `post_update_materialized_view` interceptor.
+ When both interceptors are used, this `post_update_materialized_view_with_metadata` interceptor runs after the
+ `post_update_materialized_view` interceptor. The (possibly modified) response returned by
+ `post_update_materialized_view` will be passed to
+ `post_update_materialized_view_with_metadata`.
+ """
+ return response, metadata
+
+
+@dataclasses.dataclass
+class BigtableInstanceAdminRestStub:
+ _session: AuthorizedSession
+ _host: str
+ _interceptor: BigtableInstanceAdminRestInterceptor
+
+
+class BigtableInstanceAdminRestTransport(_BaseBigtableInstanceAdminRestTransport):
+ """REST backend synchronous transport for BigtableInstanceAdmin.
+
+ Service for creating, configuring, and deleting Cloud
+ Bigtable Instances and Clusters. Provides access to the Instance
+ and Cluster schemas only, not the tables' metadata or data
+ stored in those tables.
+
+ This class defines the same methods as the primary client, so the
+ primary client can load the underlying transport implementation
+ and call it.
+
+ It sends JSON representations of protocol buffers over HTTP/1.1
+ """
+
+ def __init__(
+ self,
+ *,
+ host: str = "bigtableadmin.googleapis.com",
+ credentials: Optional[ga_credentials.Credentials] = None,
+ credentials_file: Optional[str] = None,
+ scopes: Optional[Sequence[str]] = None,
+ client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None,
+ quota_project_id: Optional[str] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ always_use_jwt_access: Optional[bool] = False,
+ url_scheme: str = "https",
+ interceptor: Optional[BigtableInstanceAdminRestInterceptor] = None,
+ api_audience: Optional[str] = None,
+ ) -> None:
+ """Instantiate the transport.
+
+ Args:
+ host (Optional[str]):
+ The hostname to connect to (default: 'bigtableadmin.googleapis.com').
+ credentials (Optional[google.auth.credentials.Credentials]): The
+ authorization credentials to attach to requests. These
+ credentials identify the application to the service; if none
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+
+ credentials_file (Optional[str]): Deprecated. A file with credentials that can
+ be loaded with :func:`google.auth.load_credentials_from_file`.
+ This argument is ignored if ``channel`` is provided. This argument will be
+ removed in the next major version of this library.
+ scopes (Optional(Sequence[str])): A list of scopes. This argument is
+ ignored if ``channel`` is provided.
+ client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client
+ certificate to configure mutual TLS HTTP channel. It is ignored
+ if ``channel`` is provided.
+ quota_project_id (Optional[str]): An optional project to use for billing
+ and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you are developing
+ your own client library.
+ always_use_jwt_access (Optional[bool]): Whether self signed JWT should
+ be used for service account credentials.
+ url_scheme: the protocol scheme for the API endpoint. Normally
+ "https", but for testing or local servers,
+ "http" can be specified.
+ """
+ # Run the base constructor
+ # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc.
+ # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the
+ # credentials object
+ super().__init__(
+ host=host,
+ credentials=credentials,
+ client_info=client_info,
+ always_use_jwt_access=always_use_jwt_access,
+ url_scheme=url_scheme,
+ api_audience=api_audience,
+ )
+ self._session = AuthorizedSession(
+ self._credentials, default_host=self.DEFAULT_HOST
+ )
+ self._operations_client: Optional[operations_v1.AbstractOperationsClient] = None
+ if client_cert_source_for_mtls:
+ self._session.configure_mtls_channel(client_cert_source_for_mtls)
+ self._interceptor = interceptor or BigtableInstanceAdminRestInterceptor()
+ self._prep_wrapped_messages(client_info)
+
+ @property
+ def operations_client(self) -> operations_v1.AbstractOperationsClient:
+ """Create the client designed to process long-running operations.
+
+ This property caches on the instance; repeated calls return the same
+ client.
+ """
+ # Only create a new client if we do not already have one.
+ if self._operations_client is None:
+ http_options: Dict[str, List[Dict[str, str]]] = {
+ "google.longrunning.Operations.CancelOperation": [
+ {
+ "method": "post",
+ "uri": "/v2/{name=operations/**}:cancel",
+ },
+ ],
+ "google.longrunning.Operations.DeleteOperation": [
+ {
+ "method": "delete",
+ "uri": "/v2/{name=operations/**}",
+ },
+ ],
+ "google.longrunning.Operations.GetOperation": [
+ {
+ "method": "get",
+ "uri": "/v2/{name=operations/**}",
+ },
+ ],
+ "google.longrunning.Operations.ListOperations": [
+ {
+ "method": "get",
+ "uri": "/v2/{name=operations/projects/**}/operations",
+ },
+ ],
+ }
+
+ rest_transport = operations_v1.OperationsRestTransport(
+ host=self._host,
+ # use the credentials which are saved
+ credentials=self._credentials,
+ scopes=self._scopes,
+ http_options=http_options,
+ path_prefix="v2",
+ )
+
+ self._operations_client = operations_v1.AbstractOperationsClient(
+ transport=rest_transport
+ )
+
+ # Return the client from cache.
+ return self._operations_client
+
+ class _CreateAppProfile(
+ _BaseBigtableInstanceAdminRestTransport._BaseCreateAppProfile,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.CreateAppProfile")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_instance_admin.CreateAppProfileRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> instance.AppProfile:
+ r"""Call the create app profile method over HTTP.
+
+ Args:
+ request (~.bigtable_instance_admin.CreateAppProfileRequest):
+ The request object. Request message for
+ BigtableInstanceAdmin.CreateAppProfile.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.instance.AppProfile:
+ A configuration object describing how
+ Cloud Bigtable should treat traffic from
+ a particular end user application.
+
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BaseCreateAppProfile._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_create_app_profile(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BaseCreateAppProfile._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableInstanceAdminRestTransport._BaseCreateAppProfile._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BaseCreateAppProfile._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.CreateAppProfile",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "CreateAppProfile",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = (
+ BigtableInstanceAdminRestTransport._CreateAppProfile._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = instance.AppProfile()
+ pb_resp = instance.AppProfile.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_create_app_profile(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_create_app_profile_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = instance.AppProfile.to_json(response)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BigtableInstanceAdminClient.create_app_profile",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "CreateAppProfile",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _CreateCluster(
+ _BaseBigtableInstanceAdminRestTransport._BaseCreateCluster,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.CreateCluster")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_instance_admin.CreateClusterRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operations_pb2.Operation:
+ r"""Call the create cluster method over HTTP.
+
+ Args:
+ request (~.bigtable_instance_admin.CreateClusterRequest):
+ The request object. Request message for
+ BigtableInstanceAdmin.CreateCluster.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.operations_pb2.Operation:
+ This resource represents a
+ long-running operation that is the
+ result of a network API call.
+
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BaseCreateCluster._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_create_cluster(request, metadata)
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BaseCreateCluster._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableInstanceAdminRestTransport._BaseCreateCluster._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BaseCreateCluster._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.CreateCluster",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "CreateCluster",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableInstanceAdminRestTransport._CreateCluster._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = operations_pb2.Operation()
+ json_format.Parse(response.content, resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_create_cluster(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_create_cluster_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = json_format.MessageToJson(resp)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BigtableInstanceAdminClient.create_cluster",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "CreateCluster",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _CreateInstance(
+ _BaseBigtableInstanceAdminRestTransport._BaseCreateInstance,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.CreateInstance")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_instance_admin.CreateInstanceRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operations_pb2.Operation:
+ r"""Call the create instance method over HTTP.
+
+ Args:
+ request (~.bigtable_instance_admin.CreateInstanceRequest):
+ The request object. Request message for
+ BigtableInstanceAdmin.CreateInstance.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.operations_pb2.Operation:
+ This resource represents a
+ long-running operation that is the
+ result of a network API call.
+
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BaseCreateInstance._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_create_instance(request, metadata)
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BaseCreateInstance._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableInstanceAdminRestTransport._BaseCreateInstance._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BaseCreateInstance._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.CreateInstance",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "CreateInstance",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableInstanceAdminRestTransport._CreateInstance._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = operations_pb2.Operation()
+ json_format.Parse(response.content, resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_create_instance(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_create_instance_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = json_format.MessageToJson(resp)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BigtableInstanceAdminClient.create_instance",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "CreateInstance",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _CreateLogicalView(
+ _BaseBigtableInstanceAdminRestTransport._BaseCreateLogicalView,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.CreateLogicalView")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_instance_admin.CreateLogicalViewRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operations_pb2.Operation:
+ r"""Call the create logical view method over HTTP.
+
+ Args:
+ request (~.bigtable_instance_admin.CreateLogicalViewRequest):
+ The request object. Request message for
+ BigtableInstanceAdmin.CreateLogicalView.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.operations_pb2.Operation:
+ This resource represents a
+ long-running operation that is the
+ result of a network API call.
+
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BaseCreateLogicalView._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_create_logical_view(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BaseCreateLogicalView._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableInstanceAdminRestTransport._BaseCreateLogicalView._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BaseCreateLogicalView._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.CreateLogicalView",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "CreateLogicalView",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = (
+ BigtableInstanceAdminRestTransport._CreateLogicalView._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = operations_pb2.Operation()
+ json_format.Parse(response.content, resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_create_logical_view(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_create_logical_view_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = json_format.MessageToJson(resp)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BigtableInstanceAdminClient.create_logical_view",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "CreateLogicalView",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _CreateMaterializedView(
+ _BaseBigtableInstanceAdminRestTransport._BaseCreateMaterializedView,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.CreateMaterializedView")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_instance_admin.CreateMaterializedViewRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operations_pb2.Operation:
+ r"""Call the create materialized view method over HTTP.
+
+ Args:
+ request (~.bigtable_instance_admin.CreateMaterializedViewRequest):
+ The request object. Request message for
+ BigtableInstanceAdmin.CreateMaterializedView.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.operations_pb2.Operation:
+ This resource represents a
+ long-running operation that is the
+ result of a network API call.
+
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BaseCreateMaterializedView._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_create_materialized_view(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BaseCreateMaterializedView._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableInstanceAdminRestTransport._BaseCreateMaterializedView._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BaseCreateMaterializedView._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.CreateMaterializedView",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "CreateMaterializedView",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableInstanceAdminRestTransport._CreateMaterializedView._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = operations_pb2.Operation()
+ json_format.Parse(response.content, resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_create_materialized_view(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_create_materialized_view_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = json_format.MessageToJson(resp)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BigtableInstanceAdminClient.create_materialized_view",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "CreateMaterializedView",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _DeleteAppProfile(
+ _BaseBigtableInstanceAdminRestTransport._BaseDeleteAppProfile,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.DeleteAppProfile")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_instance_admin.DeleteAppProfileRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ):
+ r"""Call the delete app profile method over HTTP.
+
+ Args:
+ request (~.bigtable_instance_admin.DeleteAppProfileRequest):
+ The request object. Request message for
+ BigtableInstanceAdmin.DeleteAppProfile.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BaseDeleteAppProfile._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_delete_app_profile(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BaseDeleteAppProfile._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BaseDeleteAppProfile._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.DeleteAppProfile",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "DeleteAppProfile",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = (
+ BigtableInstanceAdminRestTransport._DeleteAppProfile._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ class _DeleteCluster(
+ _BaseBigtableInstanceAdminRestTransport._BaseDeleteCluster,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.DeleteCluster")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_instance_admin.DeleteClusterRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ):
+ r"""Call the delete cluster method over HTTP.
+
+ Args:
+ request (~.bigtable_instance_admin.DeleteClusterRequest):
+ The request object. Request message for
+ BigtableInstanceAdmin.DeleteCluster.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BaseDeleteCluster._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_delete_cluster(request, metadata)
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BaseDeleteCluster._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BaseDeleteCluster._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.DeleteCluster",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "DeleteCluster",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableInstanceAdminRestTransport._DeleteCluster._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ class _DeleteInstance(
+ _BaseBigtableInstanceAdminRestTransport._BaseDeleteInstance,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.DeleteInstance")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_instance_admin.DeleteInstanceRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ):
+ r"""Call the delete instance method over HTTP.
+
+ Args:
+ request (~.bigtable_instance_admin.DeleteInstanceRequest):
+ The request object. Request message for
+ BigtableInstanceAdmin.DeleteInstance.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BaseDeleteInstance._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_delete_instance(request, metadata)
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BaseDeleteInstance._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BaseDeleteInstance._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.DeleteInstance",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "DeleteInstance",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableInstanceAdminRestTransport._DeleteInstance._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ class _DeleteLogicalView(
+ _BaseBigtableInstanceAdminRestTransport._BaseDeleteLogicalView,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.DeleteLogicalView")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_instance_admin.DeleteLogicalViewRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ):
+ r"""Call the delete logical view method over HTTP.
+
+ Args:
+ request (~.bigtable_instance_admin.DeleteLogicalViewRequest):
+ The request object. Request message for
+ BigtableInstanceAdmin.DeleteLogicalView.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BaseDeleteLogicalView._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_delete_logical_view(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BaseDeleteLogicalView._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BaseDeleteLogicalView._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.DeleteLogicalView",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "DeleteLogicalView",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = (
+ BigtableInstanceAdminRestTransport._DeleteLogicalView._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ class _DeleteMaterializedView(
+ _BaseBigtableInstanceAdminRestTransport._BaseDeleteMaterializedView,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.DeleteMaterializedView")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_instance_admin.DeleteMaterializedViewRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ):
+ r"""Call the delete materialized view method over HTTP.
+
+ Args:
+ request (~.bigtable_instance_admin.DeleteMaterializedViewRequest):
+ The request object. Request message for
+ BigtableInstanceAdmin.DeleteMaterializedView.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BaseDeleteMaterializedView._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_delete_materialized_view(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BaseDeleteMaterializedView._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BaseDeleteMaterializedView._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.DeleteMaterializedView",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "DeleteMaterializedView",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableInstanceAdminRestTransport._DeleteMaterializedView._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ class _GetAppProfile(
+ _BaseBigtableInstanceAdminRestTransport._BaseGetAppProfile,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.GetAppProfile")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_instance_admin.GetAppProfileRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> instance.AppProfile:
+ r"""Call the get app profile method over HTTP.
+
+ Args:
+ request (~.bigtable_instance_admin.GetAppProfileRequest):
+ The request object. Request message for
+ BigtableInstanceAdmin.GetAppProfile.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.instance.AppProfile:
+ A configuration object describing how
+ Cloud Bigtable should treat traffic from
+ a particular end user application.
+
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BaseGetAppProfile._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_get_app_profile(request, metadata)
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BaseGetAppProfile._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BaseGetAppProfile._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.GetAppProfile",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "GetAppProfile",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableInstanceAdminRestTransport._GetAppProfile._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = instance.AppProfile()
+ pb_resp = instance.AppProfile.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_get_app_profile(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_get_app_profile_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = instance.AppProfile.to_json(response)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BigtableInstanceAdminClient.get_app_profile",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "GetAppProfile",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _GetCluster(
+ _BaseBigtableInstanceAdminRestTransport._BaseGetCluster,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.GetCluster")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_instance_admin.GetClusterRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> instance.Cluster:
+ r"""Call the get cluster method over HTTP.
+
+ Args:
+ request (~.bigtable_instance_admin.GetClusterRequest):
+ The request object. Request message for
+ BigtableInstanceAdmin.GetCluster.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.instance.Cluster:
+ A resizable group of nodes in a particular cloud
+ location, capable of serving all
+ [Tables][google.bigtable.admin.v2.Table] in the parent
+ [Instance][google.bigtable.admin.v2.Instance].
+
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BaseGetCluster._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_get_cluster(request, metadata)
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BaseGetCluster._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BaseGetCluster._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.GetCluster",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "GetCluster",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableInstanceAdminRestTransport._GetCluster._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = instance.Cluster()
+ pb_resp = instance.Cluster.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_get_cluster(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_get_cluster_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = instance.Cluster.to_json(response)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BigtableInstanceAdminClient.get_cluster",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "GetCluster",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _GetIamPolicy(
+ _BaseBigtableInstanceAdminRestTransport._BaseGetIamPolicy,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.GetIamPolicy")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: iam_policy_pb2.GetIamPolicyRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> policy_pb2.Policy:
+ r"""Call the get iam policy method over HTTP.
+
+ Args:
+ request (~.iam_policy_pb2.GetIamPolicyRequest):
+ The request object. Request message for ``GetIamPolicy`` method.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.policy_pb2.Policy:
+ An Identity and Access Management (IAM) policy, which
+ specifies access controls for Google Cloud resources.
+
+ A ``Policy`` is a collection of ``bindings``. A
+ ``binding`` binds one or more ``members``, or
+ principals, to a single ``role``. Principals can be user
+ accounts, service accounts, Google groups, and domains
+ (such as G Suite). A ``role`` is a named list of
+ permissions; each ``role`` can be an IAM predefined role
+ or a user-created custom role.
+
+ For some types of Google Cloud resources, a ``binding``
+ can also specify a ``condition``, which is a logical
+ expression that allows access to a resource only if the
+ expression evaluates to ``true``. A condition can add
+ constraints based on attributes of the request, the
+ resource, or both. To learn which resources support
+ conditions in their IAM policies, see the `IAM
+ documentation `__.
+
+ **JSON example:**
+
+ ::
+
+ {
+ "bindings": [
+ {
+ "role": "roles/resourcemanager.organizationAdmin",
+ "members": [
+ "user:mike@example.com",
+ "group:admins@example.com",
+ "domain:google.com",
+ "serviceAccount:my-project-id@appspot.gserviceaccount.com"
+ ]
+ },
+ {
+ "role": "roles/resourcemanager.organizationViewer",
+ "members": [
+ "user:eve@example.com"
+ ],
+ "condition": {
+ "title": "expirable access",
+ "description": "Does not grant access after Sep 2020",
+ "expression": "request.time <
+ timestamp('2020-10-01T00:00:00.000Z')",
+ }
+ }
+ ],
+ "etag": "BwWWja0YfJA=",
+ "version": 3
+ }
+
+ **YAML example:**
+
+ ::
+
+ bindings:
+ - members:
+ - user:mike@example.com
+ - group:admins@example.com
+ - domain:google.com
+ - serviceAccount:my-project-id@appspot.gserviceaccount.com
+ role: roles/resourcemanager.organizationAdmin
+ - members:
+ - user:eve@example.com
+ role: roles/resourcemanager.organizationViewer
+ condition:
+ title: expirable access
+ description: Does not grant access after Sep 2020
+ expression: request.time < timestamp('2020-10-01T00:00:00.000Z')
+ etag: BwWWja0YfJA=
+ version: 3
+
+ For a description of IAM and its features, see the `IAM
+ documentation `__.
+
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BaseGetIamPolicy._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_get_iam_policy(request, metadata)
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BaseGetIamPolicy._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableInstanceAdminRestTransport._BaseGetIamPolicy._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BaseGetIamPolicy._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.GetIamPolicy",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "GetIamPolicy",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableInstanceAdminRestTransport._GetIamPolicy._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = policy_pb2.Policy()
+ pb_resp = resp
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_get_iam_policy(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_get_iam_policy_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = json_format.MessageToJson(resp)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BigtableInstanceAdminClient.get_iam_policy",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "GetIamPolicy",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _GetInstance(
+ _BaseBigtableInstanceAdminRestTransport._BaseGetInstance,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.GetInstance")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_instance_admin.GetInstanceRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> instance.Instance:
+ r"""Call the get instance method over HTTP.
+
+ Args:
+ request (~.bigtable_instance_admin.GetInstanceRequest):
+ The request object. Request message for
+ BigtableInstanceAdmin.GetInstance.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.instance.Instance:
+ A collection of Bigtable
+ [Tables][google.bigtable.admin.v2.Table] and the
+ resources that serve them. All tables in an instance are
+ served from all
+ [Clusters][google.bigtable.admin.v2.Cluster] in the
+ instance.
+
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BaseGetInstance._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_get_instance(request, metadata)
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BaseGetInstance._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BaseGetInstance._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.GetInstance",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "GetInstance",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableInstanceAdminRestTransport._GetInstance._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = instance.Instance()
+ pb_resp = instance.Instance.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_get_instance(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_get_instance_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = instance.Instance.to_json(response)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BigtableInstanceAdminClient.get_instance",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "GetInstance",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _GetLogicalView(
+ _BaseBigtableInstanceAdminRestTransport._BaseGetLogicalView,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.GetLogicalView")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_instance_admin.GetLogicalViewRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> instance.LogicalView:
+ r"""Call the get logical view method over HTTP.
+
+ Args:
+ request (~.bigtable_instance_admin.GetLogicalViewRequest):
+ The request object. Request message for
+ BigtableInstanceAdmin.GetLogicalView.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.instance.LogicalView:
+ A SQL logical view object that can be
+ referenced in SQL queries.
+
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BaseGetLogicalView._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_get_logical_view(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BaseGetLogicalView._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BaseGetLogicalView._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.GetLogicalView",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "GetLogicalView",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableInstanceAdminRestTransport._GetLogicalView._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = instance.LogicalView()
+ pb_resp = instance.LogicalView.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_get_logical_view(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_get_logical_view_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = instance.LogicalView.to_json(response)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BigtableInstanceAdminClient.get_logical_view",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "GetLogicalView",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _GetMaterializedView(
+ _BaseBigtableInstanceAdminRestTransport._BaseGetMaterializedView,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.GetMaterializedView")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_instance_admin.GetMaterializedViewRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> instance.MaterializedView:
+ r"""Call the get materialized view method over HTTP.
+
+ Args:
+ request (~.bigtable_instance_admin.GetMaterializedViewRequest):
+ The request object. Request message for
+ BigtableInstanceAdmin.GetMaterializedView.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.instance.MaterializedView:
+ A materialized view object that can
+ be referenced in SQL queries.
+
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BaseGetMaterializedView._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_get_materialized_view(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BaseGetMaterializedView._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BaseGetMaterializedView._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.GetMaterializedView",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "GetMaterializedView",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = (
+ BigtableInstanceAdminRestTransport._GetMaterializedView._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = instance.MaterializedView()
+ pb_resp = instance.MaterializedView.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_get_materialized_view(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_get_materialized_view_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = instance.MaterializedView.to_json(response)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BigtableInstanceAdminClient.get_materialized_view",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "GetMaterializedView",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _ListAppProfiles(
+ _BaseBigtableInstanceAdminRestTransport._BaseListAppProfiles,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.ListAppProfiles")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_instance_admin.ListAppProfilesRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> bigtable_instance_admin.ListAppProfilesResponse:
+ r"""Call the list app profiles method over HTTP.
+
+ Args:
+ request (~.bigtable_instance_admin.ListAppProfilesRequest):
+ The request object. Request message for
+ BigtableInstanceAdmin.ListAppProfiles.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.bigtable_instance_admin.ListAppProfilesResponse:
+ Response message for
+ BigtableInstanceAdmin.ListAppProfiles.
+
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BaseListAppProfiles._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_list_app_profiles(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BaseListAppProfiles._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BaseListAppProfiles._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.ListAppProfiles",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "ListAppProfiles",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = (
+ BigtableInstanceAdminRestTransport._ListAppProfiles._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = bigtable_instance_admin.ListAppProfilesResponse()
+ pb_resp = bigtable_instance_admin.ListAppProfilesResponse.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_list_app_profiles(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_list_app_profiles_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = (
+ bigtable_instance_admin.ListAppProfilesResponse.to_json(
+ response
+ )
+ )
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BigtableInstanceAdminClient.list_app_profiles",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "ListAppProfiles",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _ListClusters(
+ _BaseBigtableInstanceAdminRestTransport._BaseListClusters,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.ListClusters")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_instance_admin.ListClustersRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> bigtable_instance_admin.ListClustersResponse:
+ r"""Call the list clusters method over HTTP.
+
+ Args:
+ request (~.bigtable_instance_admin.ListClustersRequest):
+ The request object. Request message for
+ BigtableInstanceAdmin.ListClusters.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.bigtable_instance_admin.ListClustersResponse:
+ Response message for
+ BigtableInstanceAdmin.ListClusters.
+
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BaseListClusters._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_list_clusters(request, metadata)
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BaseListClusters._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BaseListClusters._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.ListClusters",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "ListClusters",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableInstanceAdminRestTransport._ListClusters._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = bigtable_instance_admin.ListClustersResponse()
+ pb_resp = bigtable_instance_admin.ListClustersResponse.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_list_clusters(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_list_clusters_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = (
+ bigtable_instance_admin.ListClustersResponse.to_json(response)
+ )
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BigtableInstanceAdminClient.list_clusters",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "ListClusters",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _ListHotTablets(
+ _BaseBigtableInstanceAdminRestTransport._BaseListHotTablets,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.ListHotTablets")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_instance_admin.ListHotTabletsRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> bigtable_instance_admin.ListHotTabletsResponse:
+ r"""Call the list hot tablets method over HTTP.
+
+ Args:
+ request (~.bigtable_instance_admin.ListHotTabletsRequest):
+ The request object. Request message for
+ BigtableInstanceAdmin.ListHotTablets.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.bigtable_instance_admin.ListHotTabletsResponse:
+ Response message for
+ BigtableInstanceAdmin.ListHotTablets.
+
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BaseListHotTablets._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_list_hot_tablets(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BaseListHotTablets._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BaseListHotTablets._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.ListHotTablets",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "ListHotTablets",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableInstanceAdminRestTransport._ListHotTablets._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = bigtable_instance_admin.ListHotTabletsResponse()
+ pb_resp = bigtable_instance_admin.ListHotTabletsResponse.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_list_hot_tablets(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_list_hot_tablets_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = (
+ bigtable_instance_admin.ListHotTabletsResponse.to_json(response)
+ )
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BigtableInstanceAdminClient.list_hot_tablets",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "ListHotTablets",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _ListInstances(
+ _BaseBigtableInstanceAdminRestTransport._BaseListInstances,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.ListInstances")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_instance_admin.ListInstancesRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> bigtable_instance_admin.ListInstancesResponse:
+ r"""Call the list instances method over HTTP.
+
+ Args:
+ request (~.bigtable_instance_admin.ListInstancesRequest):
+ The request object. Request message for
+ BigtableInstanceAdmin.ListInstances.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.bigtable_instance_admin.ListInstancesResponse:
+ Response message for
+ BigtableInstanceAdmin.ListInstances.
+
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BaseListInstances._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_list_instances(request, metadata)
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BaseListInstances._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BaseListInstances._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.ListInstances",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "ListInstances",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableInstanceAdminRestTransport._ListInstances._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = bigtable_instance_admin.ListInstancesResponse()
+ pb_resp = bigtable_instance_admin.ListInstancesResponse.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_list_instances(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_list_instances_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = (
+ bigtable_instance_admin.ListInstancesResponse.to_json(response)
+ )
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BigtableInstanceAdminClient.list_instances",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "ListInstances",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _ListLogicalViews(
+ _BaseBigtableInstanceAdminRestTransport._BaseListLogicalViews,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.ListLogicalViews")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_instance_admin.ListLogicalViewsRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> bigtable_instance_admin.ListLogicalViewsResponse:
+ r"""Call the list logical views method over HTTP.
+
+ Args:
+ request (~.bigtable_instance_admin.ListLogicalViewsRequest):
+ The request object. Request message for
+ BigtableInstanceAdmin.ListLogicalViews.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.bigtable_instance_admin.ListLogicalViewsResponse:
+ Response message for
+ BigtableInstanceAdmin.ListLogicalViews.
+
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BaseListLogicalViews._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_list_logical_views(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BaseListLogicalViews._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BaseListLogicalViews._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.ListLogicalViews",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "ListLogicalViews",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = (
+ BigtableInstanceAdminRestTransport._ListLogicalViews._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = bigtable_instance_admin.ListLogicalViewsResponse()
+ pb_resp = bigtable_instance_admin.ListLogicalViewsResponse.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_list_logical_views(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_list_logical_views_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = (
+ bigtable_instance_admin.ListLogicalViewsResponse.to_json(
+ response
+ )
+ )
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BigtableInstanceAdminClient.list_logical_views",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "ListLogicalViews",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _ListMaterializedViews(
+ _BaseBigtableInstanceAdminRestTransport._BaseListMaterializedViews,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.ListMaterializedViews")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_instance_admin.ListMaterializedViewsRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> bigtable_instance_admin.ListMaterializedViewsResponse:
+ r"""Call the list materialized views method over HTTP.
+
+ Args:
+ request (~.bigtable_instance_admin.ListMaterializedViewsRequest):
+ The request object. Request message for
+ BigtableInstanceAdmin.ListMaterializedViews.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.bigtable_instance_admin.ListMaterializedViewsResponse:
+ Response message for
+ BigtableInstanceAdmin.ListMaterializedViews.
+
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BaseListMaterializedViews._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_list_materialized_views(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BaseListMaterializedViews._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BaseListMaterializedViews._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.ListMaterializedViews",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "ListMaterializedViews",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = (
+ BigtableInstanceAdminRestTransport._ListMaterializedViews._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = bigtable_instance_admin.ListMaterializedViewsResponse()
+ pb_resp = bigtable_instance_admin.ListMaterializedViewsResponse.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_list_materialized_views(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_list_materialized_views_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = (
+ bigtable_instance_admin.ListMaterializedViewsResponse.to_json(
+ response
+ )
+ )
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BigtableInstanceAdminClient.list_materialized_views",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "ListMaterializedViews",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _PartialUpdateCluster(
+ _BaseBigtableInstanceAdminRestTransport._BasePartialUpdateCluster,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.PartialUpdateCluster")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_instance_admin.PartialUpdateClusterRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operations_pb2.Operation:
+ r"""Call the partial update cluster method over HTTP.
+
+ Args:
+ request (~.bigtable_instance_admin.PartialUpdateClusterRequest):
+ The request object. Request message for
+ BigtableInstanceAdmin.PartialUpdateCluster.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.operations_pb2.Operation:
+ This resource represents a
+ long-running operation that is the
+ result of a network API call.
+
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BasePartialUpdateCluster._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_partial_update_cluster(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BasePartialUpdateCluster._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableInstanceAdminRestTransport._BasePartialUpdateCluster._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BasePartialUpdateCluster._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.PartialUpdateCluster",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "PartialUpdateCluster",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = (
+ BigtableInstanceAdminRestTransport._PartialUpdateCluster._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = operations_pb2.Operation()
+ json_format.Parse(response.content, resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_partial_update_cluster(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_partial_update_cluster_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = json_format.MessageToJson(resp)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BigtableInstanceAdminClient.partial_update_cluster",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "PartialUpdateCluster",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _PartialUpdateInstance(
+ _BaseBigtableInstanceAdminRestTransport._BasePartialUpdateInstance,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.PartialUpdateInstance")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_instance_admin.PartialUpdateInstanceRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operations_pb2.Operation:
+ r"""Call the partial update instance method over HTTP.
+
+ Args:
+ request (~.bigtable_instance_admin.PartialUpdateInstanceRequest):
+ The request object. Request message for
+ BigtableInstanceAdmin.PartialUpdateInstance.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.operations_pb2.Operation:
+ This resource represents a
+ long-running operation that is the
+ result of a network API call.
+
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BasePartialUpdateInstance._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_partial_update_instance(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BasePartialUpdateInstance._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableInstanceAdminRestTransport._BasePartialUpdateInstance._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BasePartialUpdateInstance._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.PartialUpdateInstance",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "PartialUpdateInstance",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = (
+ BigtableInstanceAdminRestTransport._PartialUpdateInstance._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = operations_pb2.Operation()
+ json_format.Parse(response.content, resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_partial_update_instance(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_partial_update_instance_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = json_format.MessageToJson(resp)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BigtableInstanceAdminClient.partial_update_instance",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "PartialUpdateInstance",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _SetIamPolicy(
+ _BaseBigtableInstanceAdminRestTransport._BaseSetIamPolicy,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.SetIamPolicy")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: iam_policy_pb2.SetIamPolicyRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> policy_pb2.Policy:
+ r"""Call the set iam policy method over HTTP.
+
+ Args:
+ request (~.iam_policy_pb2.SetIamPolicyRequest):
+ The request object. Request message for ``SetIamPolicy`` method.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.policy_pb2.Policy:
+ An Identity and Access Management (IAM) policy, which
+ specifies access controls for Google Cloud resources.
+
+ A ``Policy`` is a collection of ``bindings``. A
+ ``binding`` binds one or more ``members``, or
+ principals, to a single ``role``. Principals can be user
+ accounts, service accounts, Google groups, and domains
+ (such as G Suite). A ``role`` is a named list of
+ permissions; each ``role`` can be an IAM predefined role
+ or a user-created custom role.
+
+ For some types of Google Cloud resources, a ``binding``
+ can also specify a ``condition``, which is a logical
+ expression that allows access to a resource only if the
+ expression evaluates to ``true``. A condition can add
+ constraints based on attributes of the request, the
+ resource, or both. To learn which resources support
+ conditions in their IAM policies, see the `IAM
+ documentation `__.
+
+ **JSON example:**
+
+ ::
+
+ {
+ "bindings": [
+ {
+ "role": "roles/resourcemanager.organizationAdmin",
+ "members": [
+ "user:mike@example.com",
+ "group:admins@example.com",
+ "domain:google.com",
+ "serviceAccount:my-project-id@appspot.gserviceaccount.com"
+ ]
+ },
+ {
+ "role": "roles/resourcemanager.organizationViewer",
+ "members": [
+ "user:eve@example.com"
+ ],
+ "condition": {
+ "title": "expirable access",
+ "description": "Does not grant access after Sep 2020",
+ "expression": "request.time <
+ timestamp('2020-10-01T00:00:00.000Z')",
+ }
+ }
+ ],
+ "etag": "BwWWja0YfJA=",
+ "version": 3
+ }
+
+ **YAML example:**
+
+ ::
+
+ bindings:
+ - members:
+ - user:mike@example.com
+ - group:admins@example.com
+ - domain:google.com
+ - serviceAccount:my-project-id@appspot.gserviceaccount.com
+ role: roles/resourcemanager.organizationAdmin
+ - members:
+ - user:eve@example.com
+ role: roles/resourcemanager.organizationViewer
+ condition:
+ title: expirable access
+ description: Does not grant access after Sep 2020
+ expression: request.time < timestamp('2020-10-01T00:00:00.000Z')
+ etag: BwWWja0YfJA=
+ version: 3
+
+ For a description of IAM and its features, see the `IAM
+ documentation `__.
+
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BaseSetIamPolicy._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_set_iam_policy(request, metadata)
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BaseSetIamPolicy._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableInstanceAdminRestTransport._BaseSetIamPolicy._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BaseSetIamPolicy._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.SetIamPolicy",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "SetIamPolicy",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableInstanceAdminRestTransport._SetIamPolicy._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = policy_pb2.Policy()
+ pb_resp = resp
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_set_iam_policy(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_set_iam_policy_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = json_format.MessageToJson(resp)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BigtableInstanceAdminClient.set_iam_policy",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "SetIamPolicy",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _TestIamPermissions(
+ _BaseBigtableInstanceAdminRestTransport._BaseTestIamPermissions,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.TestIamPermissions")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: iam_policy_pb2.TestIamPermissionsRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> iam_policy_pb2.TestIamPermissionsResponse:
+ r"""Call the test iam permissions method over HTTP.
+
+ Args:
+ request (~.iam_policy_pb2.TestIamPermissionsRequest):
+ The request object. Request message for ``TestIamPermissions`` method.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.iam_policy_pb2.TestIamPermissionsResponse:
+ Response message for ``TestIamPermissions`` method.
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BaseTestIamPermissions._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_test_iam_permissions(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BaseTestIamPermissions._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableInstanceAdminRestTransport._BaseTestIamPermissions._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BaseTestIamPermissions._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.TestIamPermissions",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "TestIamPermissions",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = (
+ BigtableInstanceAdminRestTransport._TestIamPermissions._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = iam_policy_pb2.TestIamPermissionsResponse()
+ pb_resp = resp
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_test_iam_permissions(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_test_iam_permissions_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = json_format.MessageToJson(resp)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BigtableInstanceAdminClient.test_iam_permissions",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "TestIamPermissions",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _UpdateAppProfile(
+ _BaseBigtableInstanceAdminRestTransport._BaseUpdateAppProfile,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.UpdateAppProfile")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_instance_admin.UpdateAppProfileRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operations_pb2.Operation:
+ r"""Call the update app profile method over HTTP.
+
+ Args:
+ request (~.bigtable_instance_admin.UpdateAppProfileRequest):
+ The request object. Request message for
+ BigtableInstanceAdmin.UpdateAppProfile.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.operations_pb2.Operation:
+ This resource represents a
+ long-running operation that is the
+ result of a network API call.
+
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BaseUpdateAppProfile._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_update_app_profile(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BaseUpdateAppProfile._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableInstanceAdminRestTransport._BaseUpdateAppProfile._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BaseUpdateAppProfile._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.UpdateAppProfile",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "UpdateAppProfile",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = (
+ BigtableInstanceAdminRestTransport._UpdateAppProfile._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = operations_pb2.Operation()
+ json_format.Parse(response.content, resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_update_app_profile(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_update_app_profile_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = json_format.MessageToJson(resp)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BigtableInstanceAdminClient.update_app_profile",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "UpdateAppProfile",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _UpdateCluster(
+ _BaseBigtableInstanceAdminRestTransport._BaseUpdateCluster,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.UpdateCluster")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: instance.Cluster,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operations_pb2.Operation:
+ r"""Call the update cluster method over HTTP.
+
+ Args:
+ request (~.instance.Cluster):
+ The request object. A resizable group of nodes in a particular cloud
+ location, capable of serving all
+ [Tables][google.bigtable.admin.v2.Table] in the parent
+ [Instance][google.bigtable.admin.v2.Instance].
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.operations_pb2.Operation:
+ This resource represents a
+ long-running operation that is the
+ result of a network API call.
+
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BaseUpdateCluster._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_update_cluster(request, metadata)
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BaseUpdateCluster._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableInstanceAdminRestTransport._BaseUpdateCluster._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BaseUpdateCluster._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.UpdateCluster",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "UpdateCluster",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableInstanceAdminRestTransport._UpdateCluster._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = operations_pb2.Operation()
+ json_format.Parse(response.content, resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_update_cluster(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_update_cluster_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = json_format.MessageToJson(resp)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BigtableInstanceAdminClient.update_cluster",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "UpdateCluster",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _UpdateInstance(
+ _BaseBigtableInstanceAdminRestTransport._BaseUpdateInstance,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.UpdateInstance")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: instance.Instance,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> instance.Instance:
+ r"""Call the update instance method over HTTP.
+
+ Args:
+ request (~.instance.Instance):
+ The request object. A collection of Bigtable
+ [Tables][google.bigtable.admin.v2.Table] and the
+ resources that serve them. All tables in an instance are
+ served from all
+ [Clusters][google.bigtable.admin.v2.Cluster] in the
+ instance.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.instance.Instance:
+ A collection of Bigtable
+ [Tables][google.bigtable.admin.v2.Table] and the
+ resources that serve them. All tables in an instance are
+ served from all
+ [Clusters][google.bigtable.admin.v2.Cluster] in the
+ instance.
+
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BaseUpdateInstance._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_update_instance(request, metadata)
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BaseUpdateInstance._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableInstanceAdminRestTransport._BaseUpdateInstance._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BaseUpdateInstance._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.UpdateInstance",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "UpdateInstance",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableInstanceAdminRestTransport._UpdateInstance._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = instance.Instance()
+ pb_resp = instance.Instance.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_update_instance(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_update_instance_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = instance.Instance.to_json(response)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BigtableInstanceAdminClient.update_instance",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "UpdateInstance",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _UpdateLogicalView(
+ _BaseBigtableInstanceAdminRestTransport._BaseUpdateLogicalView,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.UpdateLogicalView")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_instance_admin.UpdateLogicalViewRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operations_pb2.Operation:
+ r"""Call the update logical view method over HTTP.
+
+ Args:
+ request (~.bigtable_instance_admin.UpdateLogicalViewRequest):
+ The request object. Request message for
+ BigtableInstanceAdmin.UpdateLogicalView.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.operations_pb2.Operation:
+ This resource represents a
+ long-running operation that is the
+ result of a network API call.
+
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BaseUpdateLogicalView._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_update_logical_view(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BaseUpdateLogicalView._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableInstanceAdminRestTransport._BaseUpdateLogicalView._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BaseUpdateLogicalView._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.UpdateLogicalView",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "UpdateLogicalView",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = (
+ BigtableInstanceAdminRestTransport._UpdateLogicalView._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = operations_pb2.Operation()
+ json_format.Parse(response.content, resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_update_logical_view(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_update_logical_view_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = json_format.MessageToJson(resp)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BigtableInstanceAdminClient.update_logical_view",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "UpdateLogicalView",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _UpdateMaterializedView(
+ _BaseBigtableInstanceAdminRestTransport._BaseUpdateMaterializedView,
+ BigtableInstanceAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableInstanceAdminRestTransport.UpdateMaterializedView")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_instance_admin.UpdateMaterializedViewRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operations_pb2.Operation:
+ r"""Call the update materialized view method over HTTP.
+
+ Args:
+ request (~.bigtable_instance_admin.UpdateMaterializedViewRequest):
+ The request object. Request message for
+ BigtableInstanceAdmin.UpdateMaterializedView.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.operations_pb2.Operation:
+ This resource represents a
+ long-running operation that is the
+ result of a network API call.
+
+ """
+
+ http_options = (
+ _BaseBigtableInstanceAdminRestTransport._BaseUpdateMaterializedView._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_update_materialized_view(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableInstanceAdminRestTransport._BaseUpdateMaterializedView._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableInstanceAdminRestTransport._BaseUpdateMaterializedView._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableInstanceAdminRestTransport._BaseUpdateMaterializedView._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BigtableInstanceAdminClient.UpdateMaterializedView",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "UpdateMaterializedView",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableInstanceAdminRestTransport._UpdateMaterializedView._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = operations_pb2.Operation()
+ json_format.Parse(response.content, resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_update_materialized_view(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_update_materialized_view_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = json_format.MessageToJson(resp)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BigtableInstanceAdminClient.update_materialized_view",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableInstanceAdmin",
+ "rpcName": "UpdateMaterializedView",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ @property
+ def create_app_profile(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.CreateAppProfileRequest], instance.AppProfile
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._CreateAppProfile(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def create_cluster(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.CreateClusterRequest], operations_pb2.Operation
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._CreateCluster(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def create_instance(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.CreateInstanceRequest], operations_pb2.Operation
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._CreateInstance(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def create_logical_view(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.CreateLogicalViewRequest], operations_pb2.Operation
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._CreateLogicalView(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def create_materialized_view(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.CreateMaterializedViewRequest],
+ operations_pb2.Operation,
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._CreateMaterializedView(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def delete_app_profile(
+ self,
+ ) -> Callable[[bigtable_instance_admin.DeleteAppProfileRequest], empty_pb2.Empty]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._DeleteAppProfile(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def delete_cluster(
+ self,
+ ) -> Callable[[bigtable_instance_admin.DeleteClusterRequest], empty_pb2.Empty]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._DeleteCluster(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def delete_instance(
+ self,
+ ) -> Callable[[bigtable_instance_admin.DeleteInstanceRequest], empty_pb2.Empty]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._DeleteInstance(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def delete_logical_view(
+ self,
+ ) -> Callable[[bigtable_instance_admin.DeleteLogicalViewRequest], empty_pb2.Empty]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._DeleteLogicalView(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def delete_materialized_view(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.DeleteMaterializedViewRequest], empty_pb2.Empty
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._DeleteMaterializedView(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def get_app_profile(
+ self,
+ ) -> Callable[[bigtable_instance_admin.GetAppProfileRequest], instance.AppProfile]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._GetAppProfile(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def get_cluster(
+ self,
+ ) -> Callable[[bigtable_instance_admin.GetClusterRequest], instance.Cluster]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._GetCluster(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def get_iam_policy(
+ self,
+ ) -> Callable[[iam_policy_pb2.GetIamPolicyRequest], policy_pb2.Policy]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._GetIamPolicy(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def get_instance(
+ self,
+ ) -> Callable[[bigtable_instance_admin.GetInstanceRequest], instance.Instance]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._GetInstance(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def get_logical_view(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.GetLogicalViewRequest], instance.LogicalView
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._GetLogicalView(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def get_materialized_view(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.GetMaterializedViewRequest], instance.MaterializedView
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._GetMaterializedView(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def list_app_profiles(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.ListAppProfilesRequest],
+ bigtable_instance_admin.ListAppProfilesResponse,
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._ListAppProfiles(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def list_clusters(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.ListClustersRequest],
+ bigtable_instance_admin.ListClustersResponse,
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._ListClusters(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def list_hot_tablets(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.ListHotTabletsRequest],
+ bigtable_instance_admin.ListHotTabletsResponse,
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._ListHotTablets(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def list_instances(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.ListInstancesRequest],
+ bigtable_instance_admin.ListInstancesResponse,
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._ListInstances(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def list_logical_views(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.ListLogicalViewsRequest],
+ bigtable_instance_admin.ListLogicalViewsResponse,
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._ListLogicalViews(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def list_materialized_views(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.ListMaterializedViewsRequest],
+ bigtable_instance_admin.ListMaterializedViewsResponse,
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._ListMaterializedViews(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def partial_update_cluster(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.PartialUpdateClusterRequest], operations_pb2.Operation
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._PartialUpdateCluster(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def partial_update_instance(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.PartialUpdateInstanceRequest], operations_pb2.Operation
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._PartialUpdateInstance(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def set_iam_policy(
+ self,
+ ) -> Callable[[iam_policy_pb2.SetIamPolicyRequest], policy_pb2.Policy]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._SetIamPolicy(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def test_iam_permissions(
+ self,
+ ) -> Callable[
+ [iam_policy_pb2.TestIamPermissionsRequest],
+ iam_policy_pb2.TestIamPermissionsResponse,
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._TestIamPermissions(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def update_app_profile(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.UpdateAppProfileRequest], operations_pb2.Operation
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._UpdateAppProfile(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def update_cluster(self) -> Callable[[instance.Cluster], operations_pb2.Operation]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._UpdateCluster(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def update_instance(self) -> Callable[[instance.Instance], instance.Instance]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._UpdateInstance(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def update_logical_view(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.UpdateLogicalViewRequest], operations_pb2.Operation
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._UpdateLogicalView(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def update_materialized_view(
+ self,
+ ) -> Callable[
+ [bigtable_instance_admin.UpdateMaterializedViewRequest],
+ operations_pb2.Operation,
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._UpdateMaterializedView(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def kind(self) -> str:
+ return "rest"
+
+ def close(self):
+ self._session.close()
+
+
+__all__ = ("BigtableInstanceAdminRestTransport",)
diff --git a/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/rest_base.py b/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/rest_base.py
new file mode 100644
index 000000000..9855756b8
--- /dev/null
+++ b/google/cloud/bigtable_admin_v2/services/bigtable_instance_admin/transports/rest_base.py
@@ -0,0 +1,1746 @@
+# -*- coding: utf-8 -*-
+# Copyright 2025 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 json # type: ignore
+from google.api_core import path_template
+from google.api_core import gapic_v1
+
+from google.protobuf import json_format
+from .base import BigtableInstanceAdminTransport, DEFAULT_CLIENT_INFO
+
+import re
+from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union
+
+
+from google.cloud.bigtable_admin_v2.types import bigtable_instance_admin
+from google.cloud.bigtable_admin_v2.types import instance
+from google.iam.v1 import iam_policy_pb2 # type: ignore
+from google.iam.v1 import policy_pb2 # type: ignore
+from google.protobuf import empty_pb2 # type: ignore
+from google.longrunning import operations_pb2 # type: ignore
+
+
+class _BaseBigtableInstanceAdminRestTransport(BigtableInstanceAdminTransport):
+ """Base REST backend transport for BigtableInstanceAdmin.
+
+ Note: This class is not meant to be used directly. Use its sync and
+ async sub-classes instead.
+
+ This class defines the same methods as the primary client, so the
+ primary client can load the underlying transport implementation
+ and call it.
+
+ It sends JSON representations of protocol buffers over HTTP/1.1
+ """
+
+ def __init__(
+ self,
+ *,
+ host: str = "bigtableadmin.googleapis.com",
+ credentials: Optional[Any] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ always_use_jwt_access: Optional[bool] = False,
+ url_scheme: str = "https",
+ api_audience: Optional[str] = None,
+ ) -> None:
+ """Instantiate the transport.
+ Args:
+ host (Optional[str]):
+ The hostname to connect to (default: 'bigtableadmin.googleapis.com').
+ credentials (Optional[Any]): The
+ authorization credentials to attach to requests. These
+ credentials identify the application to the service; if none
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you are developing
+ your own client library.
+ always_use_jwt_access (Optional[bool]): Whether self signed JWT should
+ be used for service account credentials.
+ url_scheme: the protocol scheme for the API endpoint. Normally
+ "https", but for testing or local servers,
+ "http" can be specified.
+ """
+ # Run the base constructor
+ maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host)
+ if maybe_url_match is None:
+ raise ValueError(
+ f"Unexpected hostname structure: {host}"
+ ) # pragma: NO COVER
+
+ url_match_items = maybe_url_match.groupdict()
+
+ host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host
+
+ super().__init__(
+ host=host,
+ credentials=credentials,
+ client_info=client_info,
+ always_use_jwt_access=always_use_jwt_access,
+ api_audience=api_audience,
+ )
+
+ class _BaseCreateAppProfile:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {
+ "appProfileId": "",
+ }
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{parent=projects/*/instances/*}/appProfiles",
+ "body": "app_profile",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_instance_admin.CreateAppProfileRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableInstanceAdminRestTransport._BaseCreateAppProfile._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseCreateCluster:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {
+ "clusterId": "",
+ }
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{parent=projects/*/instances/*}/clusters",
+ "body": "cluster",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_instance_admin.CreateClusterRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableInstanceAdminRestTransport._BaseCreateCluster._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseCreateInstance:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{parent=projects/*}/instances",
+ "body": "*",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_instance_admin.CreateInstanceRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableInstanceAdminRestTransport._BaseCreateInstance._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseCreateLogicalView:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {
+ "logicalViewId": "",
+ }
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{parent=projects/*/instances/*}/logicalViews",
+ "body": "logical_view",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_instance_admin.CreateLogicalViewRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableInstanceAdminRestTransport._BaseCreateLogicalView._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseCreateMaterializedView:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {
+ "materializedViewId": "",
+ }
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{parent=projects/*/instances/*}/materializedViews",
+ "body": "materialized_view",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_instance_admin.CreateMaterializedViewRequest.pb(
+ request
+ )
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableInstanceAdminRestTransport._BaseCreateMaterializedView._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseDeleteAppProfile:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {
+ "ignoreWarnings": False,
+ }
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "delete",
+ "uri": "/v2/{name=projects/*/instances/*/appProfiles/*}",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_instance_admin.DeleteAppProfileRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableInstanceAdminRestTransport._BaseDeleteAppProfile._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseDeleteCluster:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "delete",
+ "uri": "/v2/{name=projects/*/instances/*/clusters/*}",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_instance_admin.DeleteClusterRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableInstanceAdminRestTransport._BaseDeleteCluster._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseDeleteInstance:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "delete",
+ "uri": "/v2/{name=projects/*/instances/*}",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_instance_admin.DeleteInstanceRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableInstanceAdminRestTransport._BaseDeleteInstance._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseDeleteLogicalView:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "delete",
+ "uri": "/v2/{name=projects/*/instances/*/logicalViews/*}",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_instance_admin.DeleteLogicalViewRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableInstanceAdminRestTransport._BaseDeleteLogicalView._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseDeleteMaterializedView:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "delete",
+ "uri": "/v2/{name=projects/*/instances/*/materializedViews/*}",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_instance_admin.DeleteMaterializedViewRequest.pb(
+ request
+ )
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableInstanceAdminRestTransport._BaseDeleteMaterializedView._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseGetAppProfile:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "get",
+ "uri": "/v2/{name=projects/*/instances/*/appProfiles/*}",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_instance_admin.GetAppProfileRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableInstanceAdminRestTransport._BaseGetAppProfile._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseGetCluster:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "get",
+ "uri": "/v2/{name=projects/*/instances/*/clusters/*}",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_instance_admin.GetClusterRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableInstanceAdminRestTransport._BaseGetCluster._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseGetIamPolicy:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{resource=projects/*/instances/*}:getIamPolicy",
+ "body": "*",
+ },
+ {
+ "method": "post",
+ "uri": "/v2/{resource=projects/*/instances/*/materializedViews/*}:getIamPolicy",
+ "body": "*",
+ },
+ {
+ "method": "post",
+ "uri": "/v2/{resource=projects/*/instances/*/logicalViews/*}:getIamPolicy",
+ "body": "*",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = request
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableInstanceAdminRestTransport._BaseGetIamPolicy._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseGetInstance:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "get",
+ "uri": "/v2/{name=projects/*/instances/*}",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_instance_admin.GetInstanceRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableInstanceAdminRestTransport._BaseGetInstance._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseGetLogicalView:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "get",
+ "uri": "/v2/{name=projects/*/instances/*/logicalViews/*}",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_instance_admin.GetLogicalViewRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableInstanceAdminRestTransport._BaseGetLogicalView._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseGetMaterializedView:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "get",
+ "uri": "/v2/{name=projects/*/instances/*/materializedViews/*}",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_instance_admin.GetMaterializedViewRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableInstanceAdminRestTransport._BaseGetMaterializedView._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseListAppProfiles:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "get",
+ "uri": "/v2/{parent=projects/*/instances/*}/appProfiles",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_instance_admin.ListAppProfilesRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableInstanceAdminRestTransport._BaseListAppProfiles._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseListClusters:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "get",
+ "uri": "/v2/{parent=projects/*/instances/*}/clusters",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_instance_admin.ListClustersRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableInstanceAdminRestTransport._BaseListClusters._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseListHotTablets:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "get",
+ "uri": "/v2/{parent=projects/*/instances/*/clusters/*}/hotTablets",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_instance_admin.ListHotTabletsRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableInstanceAdminRestTransport._BaseListHotTablets._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseListInstances:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "get",
+ "uri": "/v2/{parent=projects/*}/instances",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_instance_admin.ListInstancesRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableInstanceAdminRestTransport._BaseListInstances._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseListLogicalViews:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "get",
+ "uri": "/v2/{parent=projects/*/instances/*}/logicalViews",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_instance_admin.ListLogicalViewsRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableInstanceAdminRestTransport._BaseListLogicalViews._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseListMaterializedViews:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "get",
+ "uri": "/v2/{parent=projects/*/instances/*}/materializedViews",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_instance_admin.ListMaterializedViewsRequest.pb(
+ request
+ )
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableInstanceAdminRestTransport._BaseListMaterializedViews._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BasePartialUpdateCluster:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {
+ "updateMask": {},
+ }
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "patch",
+ "uri": "/v2/{cluster.name=projects/*/instances/*/clusters/*}",
+ "body": "cluster",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_instance_admin.PartialUpdateClusterRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableInstanceAdminRestTransport._BasePartialUpdateCluster._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BasePartialUpdateInstance:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {
+ "updateMask": {},
+ }
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "patch",
+ "uri": "/v2/{instance.name=projects/*/instances/*}",
+ "body": "instance",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_instance_admin.PartialUpdateInstanceRequest.pb(
+ request
+ )
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableInstanceAdminRestTransport._BasePartialUpdateInstance._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseSetIamPolicy:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{resource=projects/*/instances/*}:setIamPolicy",
+ "body": "*",
+ },
+ {
+ "method": "post",
+ "uri": "/v2/{resource=projects/*/instances/*/materializedViews/*}:setIamPolicy",
+ "body": "*",
+ },
+ {
+ "method": "post",
+ "uri": "/v2/{resource=projects/*/instances/*/logicalViews/*}:setIamPolicy",
+ "body": "*",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = request
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableInstanceAdminRestTransport._BaseSetIamPolicy._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseTestIamPermissions:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{resource=projects/*/instances/*}:testIamPermissions",
+ "body": "*",
+ },
+ {
+ "method": "post",
+ "uri": "/v2/{resource=projects/*/instances/*/materializedViews/*}:testIamPermissions",
+ "body": "*",
+ },
+ {
+ "method": "post",
+ "uri": "/v2/{resource=projects/*/instances/*/logicalViews/*}:testIamPermissions",
+ "body": "*",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = request
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableInstanceAdminRestTransport._BaseTestIamPermissions._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseUpdateAppProfile:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {
+ "updateMask": {},
+ }
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "patch",
+ "uri": "/v2/{app_profile.name=projects/*/instances/*/appProfiles/*}",
+ "body": "app_profile",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_instance_admin.UpdateAppProfileRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableInstanceAdminRestTransport._BaseUpdateAppProfile._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseUpdateCluster:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "put",
+ "uri": "/v2/{name=projects/*/instances/*/clusters/*}",
+ "body": "*",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = instance.Cluster.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseUpdateInstance:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "put",
+ "uri": "/v2/{name=projects/*/instances/*}",
+ "body": "*",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = instance.Instance.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableInstanceAdminRestTransport._BaseUpdateInstance._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseUpdateLogicalView:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "patch",
+ "uri": "/v2/{logical_view.name=projects/*/instances/*/logicalViews/*}",
+ "body": "logical_view",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_instance_admin.UpdateLogicalViewRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableInstanceAdminRestTransport._BaseUpdateLogicalView._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseUpdateMaterializedView:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "patch",
+ "uri": "/v2/{materialized_view.name=projects/*/instances/*/materializedViews/*}",
+ "body": "materialized_view",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_instance_admin.UpdateMaterializedViewRequest.pb(
+ request
+ )
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableInstanceAdminRestTransport._BaseUpdateMaterializedView._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+
+__all__ = ("_BaseBigtableInstanceAdminRestTransport",)
diff --git a/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/__init__.py b/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/__init__.py
index 515696537..c5e8544d6 100644
--- a/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/__init__.py
+++ b/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/__init__.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -13,10 +13,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
-from .client import BigtableTableAdminClient
-from .async_client import BigtableTableAdminAsyncClient
+from .client import BaseBigtableTableAdminClient
+from .async_client import BaseBigtableTableAdminAsyncClient
__all__ = (
- "BigtableTableAdminClient",
- "BigtableTableAdminAsyncClient",
+ "BaseBigtableTableAdminClient",
+ "BaseBigtableTableAdminAsyncClient",
)
diff --git a/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/async_client.py b/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/async_client.py
index 0752459ee..7f772c87c 100644
--- a/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/async_client.py
+++ b/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/async_client.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -13,23 +13,37 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+import logging as std_logging
from collections import OrderedDict
-import functools
import re
-from typing import Dict, Mapping, Optional, Sequence, Tuple, Type, Union
-import pkg_resources
+from typing import (
+ Dict,
+ Callable,
+ Mapping,
+ MutableMapping,
+ MutableSequence,
+ Optional,
+ Sequence,
+ Tuple,
+ Type,
+ Union,
+)
+
+from google.cloud.bigtable_admin_v2 import gapic_version as package_version
from google.api_core.client_options import ClientOptions
from google.api_core import exceptions as core_exceptions
from google.api_core import gapic_v1
-from google.api_core import retry as retries
+from google.api_core import retry_async as retries
from google.auth import credentials as ga_credentials # type: ignore
from google.oauth2 import service_account # type: ignore
+import google.protobuf
+
try:
- OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault]
+ OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None]
except AttributeError: # pragma: NO COVER
- OptionalRetry = Union[retries.Retry, object] # type: ignore
+ OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore
from google.api_core import operation # type: ignore
from google.api_core import operation_async # type: ignore
@@ -37,16 +51,26 @@
from google.cloud.bigtable_admin_v2.types import bigtable_table_admin
from google.cloud.bigtable_admin_v2.types import table
from google.cloud.bigtable_admin_v2.types import table as gba_table
+from google.cloud.bigtable_admin_v2.types import types
from google.iam.v1 import iam_policy_pb2 # type: ignore
from google.iam.v1 import policy_pb2 # type: ignore
from google.protobuf import field_mask_pb2 # type: ignore
from google.protobuf import timestamp_pb2 # type: ignore
from .transports.base import BigtableTableAdminTransport, DEFAULT_CLIENT_INFO
from .transports.grpc_asyncio import BigtableTableAdminGrpcAsyncIOTransport
-from .client import BigtableTableAdminClient
+from .client import BaseBigtableTableAdminClient
+
+try:
+ from google.api_core import client_logging # type: ignore
+
+ CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER
+except ImportError: # pragma: NO COVER
+ CLIENT_LOGGING_SUPPORTED = False
+_LOGGER = std_logging.getLogger(__name__)
-class BigtableTableAdminAsyncClient:
+
+class BaseBigtableTableAdminAsyncClient:
"""Service for creating, configuring, and deleting Cloud
Bigtable tables.
@@ -54,50 +78,66 @@ class BigtableTableAdminAsyncClient:
within the tables.
"""
- _client: BigtableTableAdminClient
+ _client: BaseBigtableTableAdminClient
- DEFAULT_ENDPOINT = BigtableTableAdminClient.DEFAULT_ENDPOINT
- DEFAULT_MTLS_ENDPOINT = BigtableTableAdminClient.DEFAULT_MTLS_ENDPOINT
+ # Copy defaults from the synchronous client for use here.
+ # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead.
+ DEFAULT_ENDPOINT = BaseBigtableTableAdminClient.DEFAULT_ENDPOINT
+ DEFAULT_MTLS_ENDPOINT = BaseBigtableTableAdminClient.DEFAULT_MTLS_ENDPOINT
+ _DEFAULT_ENDPOINT_TEMPLATE = BaseBigtableTableAdminClient._DEFAULT_ENDPOINT_TEMPLATE
+ _DEFAULT_UNIVERSE = BaseBigtableTableAdminClient._DEFAULT_UNIVERSE
- backup_path = staticmethod(BigtableTableAdminClient.backup_path)
- parse_backup_path = staticmethod(BigtableTableAdminClient.parse_backup_path)
- cluster_path = staticmethod(BigtableTableAdminClient.cluster_path)
- parse_cluster_path = staticmethod(BigtableTableAdminClient.parse_cluster_path)
+ authorized_view_path = staticmethod(
+ BaseBigtableTableAdminClient.authorized_view_path
+ )
+ parse_authorized_view_path = staticmethod(
+ BaseBigtableTableAdminClient.parse_authorized_view_path
+ )
+ backup_path = staticmethod(BaseBigtableTableAdminClient.backup_path)
+ parse_backup_path = staticmethod(BaseBigtableTableAdminClient.parse_backup_path)
+ cluster_path = staticmethod(BaseBigtableTableAdminClient.cluster_path)
+ parse_cluster_path = staticmethod(BaseBigtableTableAdminClient.parse_cluster_path)
crypto_key_version_path = staticmethod(
- BigtableTableAdminClient.crypto_key_version_path
+ BaseBigtableTableAdminClient.crypto_key_version_path
)
parse_crypto_key_version_path = staticmethod(
- BigtableTableAdminClient.parse_crypto_key_version_path
+ BaseBigtableTableAdminClient.parse_crypto_key_version_path
+ )
+ instance_path = staticmethod(BaseBigtableTableAdminClient.instance_path)
+ parse_instance_path = staticmethod(BaseBigtableTableAdminClient.parse_instance_path)
+ schema_bundle_path = staticmethod(BaseBigtableTableAdminClient.schema_bundle_path)
+ parse_schema_bundle_path = staticmethod(
+ BaseBigtableTableAdminClient.parse_schema_bundle_path
)
- instance_path = staticmethod(BigtableTableAdminClient.instance_path)
- parse_instance_path = staticmethod(BigtableTableAdminClient.parse_instance_path)
- snapshot_path = staticmethod(BigtableTableAdminClient.snapshot_path)
- parse_snapshot_path = staticmethod(BigtableTableAdminClient.parse_snapshot_path)
- table_path = staticmethod(BigtableTableAdminClient.table_path)
- parse_table_path = staticmethod(BigtableTableAdminClient.parse_table_path)
+ snapshot_path = staticmethod(BaseBigtableTableAdminClient.snapshot_path)
+ parse_snapshot_path = staticmethod(BaseBigtableTableAdminClient.parse_snapshot_path)
+ table_path = staticmethod(BaseBigtableTableAdminClient.table_path)
+ parse_table_path = staticmethod(BaseBigtableTableAdminClient.parse_table_path)
common_billing_account_path = staticmethod(
- BigtableTableAdminClient.common_billing_account_path
+ BaseBigtableTableAdminClient.common_billing_account_path
)
parse_common_billing_account_path = staticmethod(
- BigtableTableAdminClient.parse_common_billing_account_path
+ BaseBigtableTableAdminClient.parse_common_billing_account_path
)
- common_folder_path = staticmethod(BigtableTableAdminClient.common_folder_path)
+ common_folder_path = staticmethod(BaseBigtableTableAdminClient.common_folder_path)
parse_common_folder_path = staticmethod(
- BigtableTableAdminClient.parse_common_folder_path
+ BaseBigtableTableAdminClient.parse_common_folder_path
)
common_organization_path = staticmethod(
- BigtableTableAdminClient.common_organization_path
+ BaseBigtableTableAdminClient.common_organization_path
)
parse_common_organization_path = staticmethod(
- BigtableTableAdminClient.parse_common_organization_path
+ BaseBigtableTableAdminClient.parse_common_organization_path
)
- common_project_path = staticmethod(BigtableTableAdminClient.common_project_path)
+ common_project_path = staticmethod(BaseBigtableTableAdminClient.common_project_path)
parse_common_project_path = staticmethod(
- BigtableTableAdminClient.parse_common_project_path
+ BaseBigtableTableAdminClient.parse_common_project_path
+ )
+ common_location_path = staticmethod(
+ BaseBigtableTableAdminClient.common_location_path
)
- common_location_path = staticmethod(BigtableTableAdminClient.common_location_path)
parse_common_location_path = staticmethod(
- BigtableTableAdminClient.parse_common_location_path
+ BaseBigtableTableAdminClient.parse_common_location_path
)
@classmethod
@@ -111,9 +151,9 @@ def from_service_account_info(cls, info: dict, *args, **kwargs):
kwargs: Additional arguments to pass to the constructor.
Returns:
- BigtableTableAdminAsyncClient: The constructed client.
+ BaseBigtableTableAdminAsyncClient: The constructed client.
"""
- return BigtableTableAdminClient.from_service_account_info.__func__(BigtableTableAdminAsyncClient, info, *args, **kwargs) # type: ignore
+ return BaseBigtableTableAdminClient.from_service_account_info.__func__(BaseBigtableTableAdminAsyncClient, info, *args, **kwargs) # type: ignore
@classmethod
def from_service_account_file(cls, filename: str, *args, **kwargs):
@@ -127,9 +167,9 @@ def from_service_account_file(cls, filename: str, *args, **kwargs):
kwargs: Additional arguments to pass to the constructor.
Returns:
- BigtableTableAdminAsyncClient: The constructed client.
+ BaseBigtableTableAdminAsyncClient: The constructed client.
"""
- return BigtableTableAdminClient.from_service_account_file.__func__(BigtableTableAdminAsyncClient, filename, *args, **kwargs) # type: ignore
+ return BaseBigtableTableAdminClient.from_service_account_file.__func__(BaseBigtableTableAdminAsyncClient, filename, *args, **kwargs) # type: ignore
from_service_account_json = from_service_account_file
@@ -149,7 +189,7 @@ def get_mtls_endpoint_and_cert_source(
The API endpoint is determined in the following order:
(1) if `client_options.api_endpoint` if provided, use the provided one.
(2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the
- default mTLS endpoint; if the environment variabel is "never", use the default API
+ default mTLS endpoint; if the environment variable is "never", use the default API
endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise
use the default API endpoint.
@@ -167,7 +207,7 @@ def get_mtls_endpoint_and_cert_source(
Raises:
google.auth.exceptions.MutualTLSChannelError: If any errors happen.
"""
- return BigtableTableAdminClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore
+ return BaseBigtableTableAdminClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore
@property
def transport(self) -> BigtableTableAdminTransport:
@@ -178,20 +218,42 @@ def transport(self) -> BigtableTableAdminTransport:
"""
return self._client.transport
- get_transport_class = functools.partial(
- type(BigtableTableAdminClient).get_transport_class,
- type(BigtableTableAdminClient),
- )
+ @property
+ def api_endpoint(self):
+ """Return the API endpoint used by the client instance.
+
+ Returns:
+ str: The API endpoint used by the client instance.
+ """
+ return self._client._api_endpoint
+
+ @property
+ def universe_domain(self) -> str:
+ """Return the universe domain used by the client instance.
+
+ Returns:
+ str: The universe domain used
+ by the client instance.
+ """
+ return self._client._universe_domain
+
+ get_transport_class = BaseBigtableTableAdminClient.get_transport_class
def __init__(
self,
*,
- credentials: ga_credentials.Credentials = None,
- transport: Union[str, BigtableTableAdminTransport] = "grpc_asyncio",
- client_options: ClientOptions = None,
+ credentials: Optional[ga_credentials.Credentials] = None,
+ transport: Optional[
+ Union[
+ str,
+ BigtableTableAdminTransport,
+ Callable[..., BigtableTableAdminTransport],
+ ]
+ ] = "grpc_asyncio",
+ client_options: Optional[ClientOptions] = None,
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
- """Instantiates the bigtable table admin client.
+ """Instantiates the base bigtable table admin async client.
Args:
credentials (Optional[google.auth.credentials.Credentials]): The
@@ -199,54 +261,120 @@ def __init__(
credentials identify the application to the service; if none
are specified, the client will attempt to ascertain the
credentials from the environment.
- transport (Union[str, ~.BigtableTableAdminTransport]): The
- transport to use. If set to None, a transport is chosen
- automatically.
- client_options (ClientOptions): Custom options for the client. It
- won't take effect if a ``transport`` instance is provided.
- (1) The ``api_endpoint`` property can be used to override the
- default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
- environment variable can also be used to override the endpoint:
+ transport (Optional[Union[str,BigtableTableAdminTransport,Callable[..., BigtableTableAdminTransport]]]):
+ The transport to use, or a Callable that constructs and returns a new transport to use.
+ If a Callable is given, it will be called with the same set of initialization
+ arguments as used in the BigtableTableAdminTransport constructor.
+ If set to None, a transport is chosen automatically.
+ client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]):
+ Custom options for the client.
+
+ 1. The ``api_endpoint`` property can be used to override the
+ default endpoint provided by the client when ``transport`` is
+ not explicitly provided. Only if this property is not set and
+ ``transport`` was not explicitly provided, the endpoint is
+ determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment
+ variable, which have one of the following values:
"always" (always use the default mTLS endpoint), "never" (always
- use the default regular endpoint) and "auto" (auto switch to the
- default mTLS endpoint if client certificate is present, this is
- the default value). However, the ``api_endpoint`` property takes
- precedence if provided.
- (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ use the default regular endpoint) and "auto" (auto-switch to the
+ default mTLS endpoint if client certificate is present; this is
+ the default value).
+
+ 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
is "true", then the ``client_cert_source`` property can be used
- to provide client certificate for mutual TLS transport. If
+ to provide a client certificate for mTLS transport. If
not provided, the default SSL client certificate will be used if
present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
set, no client certificate will be used.
+ 3. The ``universe_domain`` property can be used to override the
+ default "googleapis.com" universe. Note that ``api_endpoint``
+ property still takes precedence; and ``universe_domain`` is
+ currently not supported for mTLS.
+
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
+
Raises:
google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
creation failed for any reason.
"""
- self._client = BigtableTableAdminClient(
+ self._client = BaseBigtableTableAdminClient(
credentials=credentials,
transport=transport,
client_options=client_options,
client_info=client_info,
)
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ std_logging.DEBUG
+ ): # pragma: NO COVER
+ _LOGGER.debug(
+ "Created client `google.bigtable.admin_v2.BaseBigtableTableAdminAsyncClient`.",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "universeDomain": getattr(
+ self._client._transport._credentials, "universe_domain", ""
+ ),
+ "credentialsType": f"{type(self._client._transport._credentials).__module__}.{type(self._client._transport._credentials).__qualname__}",
+ "credentialsInfo": getattr(
+ self.transport._credentials, "get_cred_info", lambda: None
+ )(),
+ }
+ if hasattr(self._client._transport, "_credentials")
+ else {
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "credentialsType": None,
+ },
+ )
+
async def create_table(
self,
- request: Union[bigtable_table_admin.CreateTableRequest, dict] = None,
+ request: Optional[Union[bigtable_table_admin.CreateTableRequest, dict]] = None,
*,
- parent: str = None,
- table_id: str = None,
- table: gba_table.Table = None,
+ parent: Optional[str] = None,
+ table_id: Optional[str] = None,
+ table: Optional[gba_table.Table] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> gba_table.Table:
r"""Creates a new table in the specified instance.
The table can be created with a full set of initial
column families, specified in the request.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_create_table():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.CreateTableRequest(
+ parent="parent_value",
+ table_id="table_id_value",
+ )
+
+ # Make the request
+ response = await client.create_table(request=request)
+
+ # Handle the response
+ print(response)
+
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.CreateTableRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.CreateTableRequest, dict]]):
The request object. Request message for
[google.bigtable.admin.v2.BigtableTableAdmin.CreateTable][google.bigtable.admin.v2.BigtableTableAdmin.CreateTable]
parent (:class:`str`):
@@ -271,11 +399,13 @@ async def create_table(
This corresponds to the ``table`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_admin_v2.types.Table:
@@ -286,16 +416,22 @@ async def create_table(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([parent, table_id, table])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent, table_id, table]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_table_admin.CreateTableRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.CreateTableRequest):
+ request = bigtable_table_admin.CreateTableRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
@@ -308,11 +444,9 @@ async def create_table(
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.create_table,
- default_timeout=300.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.create_table
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -320,6 +454,9 @@ async def create_table(
gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -333,20 +470,21 @@ async def create_table(
async def create_table_from_snapshot(
self,
- request: Union[
- bigtable_table_admin.CreateTableFromSnapshotRequest, dict
+ request: Optional[
+ Union[bigtable_table_admin.CreateTableFromSnapshotRequest, dict]
] = None,
*,
- parent: str = None,
- table_id: str = None,
- source_snapshot: str = None,
+ parent: Optional[str] = None,
+ table_id: Optional[str] = None,
+ source_snapshot: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> operation_async.AsyncOperation:
r"""Creates a new table from the specified snapshot. The
target table must not exist. The snapshot and the table
must be in the same instance.
+
Note: This is a private alpha release of Cloud Bigtable
snapshots. This feature is not currently available to
most Cloud Bigtable customers. This feature might be
@@ -354,10 +492,43 @@ async def create_table_from_snapshot(
recommended for production use. It is not subject to any
SLA or deprecation policy.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_create_table_from_snapshot():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.CreateTableFromSnapshotRequest(
+ parent="parent_value",
+ table_id="table_id_value",
+ source_snapshot="source_snapshot_value",
+ )
+
+ # Make the request
+ operation = client.create_table_from_snapshot(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = (await operation).result()
+
+ # Handle the response
+ print(response)
+
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.CreateTableFromSnapshotRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.CreateTableFromSnapshotRequest, dict]]):
The request object. Request message for
[google.bigtable.admin.v2.BigtableTableAdmin.CreateTableFromSnapshot][google.bigtable.admin.v2.BigtableTableAdmin.CreateTableFromSnapshot]
+
Note: This is a private alpha release of Cloud Bigtable
snapshots. This feature is not currently available to
most Cloud Bigtable customers. This feature might be
@@ -389,11 +560,13 @@ async def create_table_from_snapshot(
This corresponds to the ``source_snapshot`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.api_core.operation_async.AsyncOperation:
@@ -405,16 +578,22 @@ async def create_table_from_snapshot(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([parent, table_id, source_snapshot])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent, table_id, source_snapshot]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_table_admin.CreateTableFromSnapshotRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.CreateTableFromSnapshotRequest):
+ request = bigtable_table_admin.CreateTableFromSnapshotRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
@@ -427,11 +606,9 @@ async def create_table_from_snapshot(
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.create_table_from_snapshot,
- default_timeout=None,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.create_table_from_snapshot
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -439,6 +616,9 @@ async def create_table_from_snapshot(
gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -460,17 +640,44 @@ async def create_table_from_snapshot(
async def list_tables(
self,
- request: Union[bigtable_table_admin.ListTablesRequest, dict] = None,
+ request: Optional[Union[bigtable_table_admin.ListTablesRequest, dict]] = None,
*,
- parent: str = None,
+ parent: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> pagers.ListTablesAsyncPager:
r"""Lists all tables served from a specified instance.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_list_tables():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.ListTablesRequest(
+ parent="parent_value",
+ )
+
+ # Make the request
+ page_result = client.list_tables(request=request)
+
+ # Handle the response
+ async for response in page_result:
+ print(response)
+
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.ListTablesRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.ListTablesRequest, dict]]):
The request object. Request message for
[google.bigtable.admin.v2.BigtableTableAdmin.ListTables][google.bigtable.admin.v2.BigtableTableAdmin.ListTables]
parent (:class:`str`):
@@ -481,11 +688,13 @@ async def list_tables(
This corresponds to the ``parent`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_admin_v2.services.bigtable_table_admin.pagers.ListTablesAsyncPager:
@@ -497,16 +706,22 @@ async def list_tables(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([parent])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_table_admin.ListTablesRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.ListTablesRequest):
+ request = bigtable_table_admin.ListTablesRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
@@ -515,21 +730,9 @@ async def list_tables(
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.list_tables,
- default_retry=retries.Retry(
- initial=1.0,
- maximum=60.0,
- multiplier=2,
- predicate=retries.if_exception_type(
- core_exceptions.DeadlineExceeded,
- core_exceptions.ServiceUnavailable,
- ),
- deadline=60.0,
- ),
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.list_tables
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -537,6 +740,9 @@ async def list_tables(
gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -551,6 +757,8 @@ async def list_tables(
method=rpc,
request=request,
response=response,
+ retry=retry,
+ timeout=timeout,
metadata=metadata,
)
@@ -559,17 +767,43 @@ async def list_tables(
async def get_table(
self,
- request: Union[bigtable_table_admin.GetTableRequest, dict] = None,
+ request: Optional[Union[bigtable_table_admin.GetTableRequest, dict]] = None,
*,
- name: str = None,
+ name: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> table.Table:
r"""Gets metadata information about the specified table.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_get_table():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.GetTableRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ response = await client.get_table(request=request)
+
+ # Handle the response
+ print(response)
+
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.GetTableRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.GetTableRequest, dict]]):
The request object. Request message for
[google.bigtable.admin.v2.BigtableTableAdmin.GetTable][google.bigtable.admin.v2.BigtableTableAdmin.GetTable]
name (:class:`str`):
@@ -580,11 +814,13 @@ async def get_table(
This corresponds to the ``name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_admin_v2.types.Table:
@@ -595,16 +831,22 @@ async def get_table(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_table_admin.GetTableRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.GetTableRequest):
+ request = bigtable_table_admin.GetTableRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
@@ -613,21 +855,9 @@ async def get_table(
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.get_table,
- default_retry=retries.Retry(
- initial=1.0,
- maximum=60.0,
- multiplier=2,
- predicate=retries.if_exception_type(
- core_exceptions.DeadlineExceeded,
- core_exceptions.ServiceUnavailable,
- ),
- deadline=60.0,
- ),
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.get_table
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -635,6 +865,9 @@ async def get_table(
gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -646,157 +879,239 @@ async def get_table(
# Done; return the response.
return response
- async def delete_table(
+ async def update_table(
self,
- request: Union[bigtable_table_admin.DeleteTableRequest, dict] = None,
+ request: Optional[Union[bigtable_table_admin.UpdateTableRequest, dict]] = None,
*,
- name: str = None,
+ table: Optional[gba_table.Table] = None,
+ update_mask: Optional[field_mask_pb2.FieldMask] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
- ) -> None:
- r"""Permanently deletes a specified table and all of its
- data.
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operation_async.AsyncOperation:
+ r"""Updates a specified table.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_update_table():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.UpdateTableRequest(
+ )
+
+ # Make the request
+ operation = client.update_table(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = (await operation).result()
+
+ # Handle the response
+ print(response)
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.DeleteTableRequest, dict]):
- The request object. Request message for
- [google.bigtable.admin.v2.BigtableTableAdmin.DeleteTable][google.bigtable.admin.v2.BigtableTableAdmin.DeleteTable]
- name (:class:`str`):
- Required. The unique name of the table to be deleted.
- Values are of the form
- ``projects/{project}/instances/{instance}/tables/{table}``.
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.UpdateTableRequest, dict]]):
+ The request object. The request for
+ [UpdateTable][google.bigtable.admin.v2.BigtableTableAdmin.UpdateTable].
+ table (:class:`google.cloud.bigtable_admin_v2.types.Table`):
+ Required. The table to update. The table's ``name``
+ field is used to identify the table to update.
- This corresponds to the ``name`` field
+ This corresponds to the ``table`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`):
+ Required. The list of fields to update. A mask
+ specifying which fields (e.g. ``change_stream_config``)
+ in the ``table`` field should be updated. This mask is
+ relative to the ``table`` field, not to the request
+ message. The wildcard (\*) path is currently not
+ supported. Currently UpdateTable is only supported for
+ the following fields:
+
+ - ``change_stream_config``
+ - ``change_stream_config.retention_period``
+ - ``deletion_protection``
+ - ``row_key_schema``
+
+ If ``column_families`` is set in ``update_mask``, it
+ will return an UNIMPLEMENTED error.
+
+ This corresponds to the ``update_mask`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.api_core.operation_async.AsyncOperation:
+ An object representing a long-running operation.
+
+ The result type for the operation will be :class:`google.cloud.bigtable_admin_v2.types.Table` A collection of user data indexed by row, column, and timestamp.
+ Each table is served using the resources of its
+ parent cluster.
+
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [table, update_mask]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_table_admin.DeleteTableRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.UpdateTableRequest):
+ request = bigtable_table_admin.UpdateTableRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
- if name is not None:
- request.name = name
+ if table is not None:
+ request.table = table
+ if update_mask is not None:
+ request.update_mask = update_mask
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.delete_table,
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.update_table
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ gapic_v1.routing_header.to_grpc_metadata(
+ (("table.name", request.table.name),)
+ ),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
- await rpc(
+ response = await rpc(
request,
retry=retry,
timeout=timeout,
metadata=metadata,
)
- async def modify_column_families(
+ # Wrap the response in an operation future.
+ response = operation_async.from_gapic(
+ response,
+ self._client._transport.operations_client,
+ gba_table.Table,
+ metadata_type=bigtable_table_admin.UpdateTableMetadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ async def delete_table(
self,
- request: Union[bigtable_table_admin.ModifyColumnFamiliesRequest, dict] = None,
+ request: Optional[Union[bigtable_table_admin.DeleteTableRequest, dict]] = None,
*,
- name: str = None,
- modifications: Sequence[
- bigtable_table_admin.ModifyColumnFamiliesRequest.Modification
- ] = None,
+ name: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
- ) -> table.Table:
- r"""Performs a series of column family modifications on
- the specified table. Either all or none of the
- modifications will occur before this method returns, but
- data requests received prior to that point may see a
- table where only some modifications have taken effect.
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> None:
+ r"""Permanently deletes a specified table and all of its
+ data.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_delete_table():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.DeleteTableRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ await client.delete_table(request=request)
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.ModifyColumnFamiliesRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.DeleteTableRequest, dict]]):
The request object. Request message for
- [google.bigtable.admin.v2.BigtableTableAdmin.ModifyColumnFamilies][google.bigtable.admin.v2.BigtableTableAdmin.ModifyColumnFamilies]
+ [google.bigtable.admin.v2.BigtableTableAdmin.DeleteTable][google.bigtable.admin.v2.BigtableTableAdmin.DeleteTable]
name (:class:`str`):
- Required. The unique name of the table whose families
- should be modified. Values are of the form
+ Required. The unique name of the table to be deleted.
+ Values are of the form
``projects/{project}/instances/{instance}/tables/{table}``.
This corresponds to the ``name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- modifications (:class:`Sequence[google.cloud.bigtable_admin_v2.types.ModifyColumnFamiliesRequest.Modification]`):
- Required. Modifications to be
- atomically applied to the specified
- table's families. Entries are applied in
- order, meaning that earlier
- modifications can be masked by later
- ones (in the case of repeated updates to
- the same family, for example).
-
- This corresponds to the ``modifications`` field
- on the ``request`` instance; if ``request`` is provided, this
- should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
-
- Returns:
- google.cloud.bigtable_admin_v2.types.Table:
- A collection of user data indexed by
- row, column, and timestamp. Each table
- is served using the resources of its
- parent cluster.
-
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name, modifications])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_table_admin.ModifyColumnFamiliesRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.DeleteTableRequest):
+ request = bigtable_table_admin.DeleteTableRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
if name is not None:
request.name = name
- if modifications:
- request.modifications.extend(modifications)
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.modify_column_families,
- default_timeout=300.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.delete_table
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -804,117 +1119,107 @@ async def modify_column_families(
gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
- response = await rpc(
+ await rpc(
request,
retry=retry,
timeout=timeout,
metadata=metadata,
)
- # Done; return the response.
- return response
-
- async def drop_row_range(
+ async def undelete_table(
self,
- request: Union[bigtable_table_admin.DropRowRangeRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_table_admin.UndeleteTableRequest, dict]
+ ] = None,
*,
+ name: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
- ) -> None:
- r"""Permanently drop/delete a row range from a specified
- table. The request can specify whether to delete all
- rows in a table, or only those that match a particular
- prefix.
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operation_async.AsyncOperation:
+ r"""Restores a specified table which was accidentally
+ deleted.
- Args:
- request (Union[google.cloud.bigtable_admin_v2.types.DropRowRangeRequest, dict]):
- The request object. Request message for
- [google.bigtable.admin.v2.BigtableTableAdmin.DropRowRange][google.bigtable.admin.v2.BigtableTableAdmin.DropRowRange]
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
- should be retried.
- timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
- """
- # Create or coerce a protobuf request object.
- request = bigtable_table_admin.DropRowRangeRequest(request)
+ .. code-block:: python
- # Wrap the RPC method; this adds retry and timeout information,
- # and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.drop_row_range,
- default_timeout=3600.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
- # Certain fields should be provided within the metadata header;
- # add these here.
- metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
- )
+ async def sample_undelete_table():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
- # Send the request.
- await rpc(
- request,
- retry=retry,
- timeout=timeout,
- metadata=metadata,
- )
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.UndeleteTableRequest(
+ name="name_value",
+ )
- async def generate_consistency_token(
- self,
- request: Union[
- bigtable_table_admin.GenerateConsistencyTokenRequest, dict
- ] = None,
- *,
- name: str = None,
- retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
- ) -> bigtable_table_admin.GenerateConsistencyTokenResponse:
- r"""Generates a consistency token for a Table, which can
- be used in CheckConsistency to check whether mutations
- to the table that finished before this call started have
- been replicated. The tokens will be available for 90
- days.
+ # Make the request
+ operation = client.undelete_table(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = (await operation).result()
+
+ # Handle the response
+ print(response)
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.GenerateConsistencyTokenRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.UndeleteTableRequest, dict]]):
The request object. Request message for
- [google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken][google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken]
+ [google.bigtable.admin.v2.BigtableTableAdmin.UndeleteTable][google.bigtable.admin.v2.BigtableTableAdmin.UndeleteTable]
name (:class:`str`):
- Required. The unique name of the Table for which to
- create a consistency token. Values are of the form
+ Required. The unique name of the table to be restored.
+ Values are of the form
``projects/{project}/instances/{instance}/tables/{table}``.
This corresponds to the ``name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
- google.cloud.bigtable_admin_v2.types.GenerateConsistencyTokenResponse:
- Response message for
- [google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken][google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken]
+ google.api_core.operation_async.AsyncOperation:
+ An object representing a long-running operation.
+
+ The result type for the operation will be :class:`google.cloud.bigtable_admin_v2.types.Table` A collection of user data indexed by row, column, and timestamp.
+ Each table is served using the resources of its
+ parent cluster.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_table_admin.GenerateConsistencyTokenRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.UndeleteTableRequest):
+ request = bigtable_table_admin.UndeleteTableRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
@@ -923,21 +1228,9 @@ async def generate_consistency_token(
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.generate_consistency_token,
- default_retry=retries.Retry(
- initial=1.0,
- maximum=60.0,
- multiplier=2,
- predicate=retries.if_exception_type(
- core_exceptions.DeadlineExceeded,
- core_exceptions.ServiceUnavailable,
- ),
- deadline=60.0,
- ),
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.undelete_table
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -945,6 +1238,9 @@ async def generate_consistency_token(
gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -953,98 +1249,152 @@ async def generate_consistency_token(
metadata=metadata,
)
+ # Wrap the response in an operation future.
+ response = operation_async.from_gapic(
+ response,
+ self._client._transport.operations_client,
+ table.Table,
+ metadata_type=bigtable_table_admin.UndeleteTableMetadata,
+ )
+
# Done; return the response.
return response
- async def check_consistency(
+ async def create_authorized_view(
self,
- request: Union[bigtable_table_admin.CheckConsistencyRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_table_admin.CreateAuthorizedViewRequest, dict]
+ ] = None,
*,
- name: str = None,
- consistency_token: str = None,
+ parent: Optional[str] = None,
+ authorized_view: Optional[table.AuthorizedView] = None,
+ authorized_view_id: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
- ) -> bigtable_table_admin.CheckConsistencyResponse:
- r"""Checks replication consistency based on a consistency
- token, that is, if replication has caught up based on
- the conditions specified in the token and the check
- request.
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operation_async.AsyncOperation:
+ r"""Creates a new AuthorizedView in a table.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_create_authorized_view():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.CreateAuthorizedViewRequest(
+ parent="parent_value",
+ authorized_view_id="authorized_view_id_value",
+ )
+
+ # Make the request
+ operation = client.create_authorized_view(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = (await operation).result()
+
+ # Handle the response
+ print(response)
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.CheckConsistencyRequest, dict]):
- The request object. Request message for
- [google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency][google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency]
- name (:class:`str`):
- Required. The unique name of the Table for which to
- check replication consistency. Values are of the form
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.CreateAuthorizedViewRequest, dict]]):
+ The request object. The request for
+ [CreateAuthorizedView][google.bigtable.admin.v2.BigtableTableAdmin.CreateAuthorizedView]
+ parent (:class:`str`):
+ Required. This is the name of the table the
+ AuthorizedView belongs to. Values are of the form
``projects/{project}/instances/{instance}/tables/{table}``.
- This corresponds to the ``name`` field
+ This corresponds to the ``parent`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- consistency_token (:class:`str`):
- Required. The token created using
- GenerateConsistencyToken for the Table.
+ authorized_view (:class:`google.cloud.bigtable_admin_v2.types.AuthorizedView`):
+ Required. The AuthorizedView to
+ create.
- This corresponds to the ``consistency_token`` field
+ This corresponds to the ``authorized_view`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ authorized_view_id (:class:`str`):
+ Required. The id of the AuthorizedView to create. This
+ AuthorizedView must not already exist. The
+ ``authorized_view_id`` appended to ``parent`` forms the
+ full AuthorizedView name of the form
+ ``projects/{project}/instances/{instance}/tables/{table}/authorizedView/{authorized_view}``.
+
+ This corresponds to the ``authorized_view_id`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
- google.cloud.bigtable_admin_v2.types.CheckConsistencyResponse:
- Response message for
- [google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency][google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency]
+ google.api_core.operation_async.AsyncOperation:
+ An object representing a long-running operation.
+
+ The result type for the operation will be :class:`google.cloud.bigtable_admin_v2.types.AuthorizedView` AuthorizedViews represent subsets of a particular Cloud Bigtable table. Users
+ can configure access to each Authorized View
+ independently from the table and use the existing
+ Data APIs to access the subset of data.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name, consistency_token])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent, authorized_view, authorized_view_id]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_table_admin.CheckConsistencyRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.CreateAuthorizedViewRequest):
+ request = bigtable_table_admin.CreateAuthorizedViewRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
- if name is not None:
- request.name = name
- if consistency_token is not None:
- request.consistency_token = consistency_token
+ if parent is not None:
+ request.parent = parent
+ if authorized_view is not None:
+ request.authorized_view = authorized_view
+ if authorized_view_id is not None:
+ request.authorized_view_id = authorized_view_id
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.check_consistency,
- default_retry=retries.Retry(
- initial=1.0,
- maximum=60.0,
- multiplier=2,
- predicate=retries.if_exception_type(
- core_exceptions.DeadlineExceeded,
- core_exceptions.ServiceUnavailable,
- ),
- deadline=60.0,
- ),
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.create_authorized_view
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -1053,131 +1403,124 @@ async def check_consistency(
metadata=metadata,
)
+ # Wrap the response in an operation future.
+ response = operation_async.from_gapic(
+ response,
+ self._client._transport.operations_client,
+ table.AuthorizedView,
+ metadata_type=bigtable_table_admin.CreateAuthorizedViewMetadata,
+ )
+
# Done; return the response.
return response
- async def snapshot_table(
+ async def list_authorized_views(
self,
- request: Union[bigtable_table_admin.SnapshotTableRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_table_admin.ListAuthorizedViewsRequest, dict]
+ ] = None,
*,
- name: str = None,
- cluster: str = None,
- snapshot_id: str = None,
- description: str = None,
+ parent: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
- ) -> operation_async.AsyncOperation:
- r"""Creates a new snapshot in the specified cluster from
- the specified source table. The cluster and the table
- must be in the same instance.
- Note: This is a private alpha release of Cloud Bigtable
- snapshots. This feature is not currently available to
- most Cloud Bigtable customers. This feature might be
- changed in backward-incompatible ways and is not
- recommended for production use. It is not subject to any
- SLA or deprecation policy.
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> pagers.ListAuthorizedViewsAsyncPager:
+ r"""Lists all AuthorizedViews from a specific table.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_list_authorized_views():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.ListAuthorizedViewsRequest(
+ parent="parent_value",
+ )
+
+ # Make the request
+ page_result = client.list_authorized_views(request=request)
+
+ # Handle the response
+ async for response in page_result:
+ print(response)
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.SnapshotTableRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.ListAuthorizedViewsRequest, dict]]):
The request object. Request message for
- [google.bigtable.admin.v2.BigtableTableAdmin.SnapshotTable][google.bigtable.admin.v2.BigtableTableAdmin.SnapshotTable]
- Note: This is a private alpha release of Cloud Bigtable
- snapshots. This feature is not currently available to
- most Cloud Bigtable customers. This feature might be
- changed in backward-incompatible ways and is not
- recommended for production use. It is not subject to any
- SLA or deprecation policy.
- name (:class:`str`):
- Required. The unique name of the table to have the
- snapshot taken. Values are of the form
+ [google.bigtable.admin.v2.BigtableTableAdmin.ListAuthorizedViews][google.bigtable.admin.v2.BigtableTableAdmin.ListAuthorizedViews]
+ parent (:class:`str`):
+ Required. The unique name of the table for which
+ AuthorizedViews should be listed. Values are of the form
``projects/{project}/instances/{instance}/tables/{table}``.
- This corresponds to the ``name`` field
- on the ``request`` instance; if ``request`` is provided, this
- should not be set.
- cluster (:class:`str`):
- Required. The name of the cluster where the snapshot
- will be created in. Values are of the form
- ``projects/{project}/instances/{instance}/clusters/{cluster}``.
-
- This corresponds to the ``cluster`` field
- on the ``request`` instance; if ``request`` is provided, this
- should not be set.
- snapshot_id (:class:`str`):
- Required. The ID by which the new snapshot should be
- referred to within the parent cluster, e.g.,
- ``mysnapshot`` of the form:
- ``[_a-zA-Z0-9][-_.a-zA-Z0-9]*`` rather than
- ``projects/{project}/instances/{instance}/clusters/{cluster}/snapshots/mysnapshot``.
-
- This corresponds to the ``snapshot_id`` field
- on the ``request`` instance; if ``request`` is provided, this
- should not be set.
- description (:class:`str`):
- Description of the snapshot.
- This corresponds to the ``description`` field
+ This corresponds to the ``parent`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
- google.api_core.operation_async.AsyncOperation:
- An object representing a long-running operation.
-
- The result type for the operation will be :class:`google.cloud.bigtable_admin_v2.types.Snapshot` A snapshot of a table at a particular time. A snapshot can be used as a
- checkpoint for data restoration or a data source for
- a new table.
+ google.cloud.bigtable_admin_v2.services.bigtable_table_admin.pagers.ListAuthorizedViewsAsyncPager:
+ Response message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.ListAuthorizedViews][google.bigtable.admin.v2.BigtableTableAdmin.ListAuthorizedViews]
- Note: This is a private alpha release of Cloud
- Bigtable snapshots. This feature is not currently
- available to most Cloud Bigtable customers. This
- feature might be changed in backward-incompatible
- ways and is not recommended for production use. It is
- not subject to any SLA or deprecation policy.
+ Iterating over this object will yield results and
+ resolve additional pages automatically.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name, cluster, snapshot_id, description])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_table_admin.SnapshotTableRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.ListAuthorizedViewsRequest):
+ request = bigtable_table_admin.ListAuthorizedViewsRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
- if name is not None:
- request.name = name
- if cluster is not None:
- request.cluster = cluster
- if snapshot_id is not None:
- request.snapshot_id = snapshot_id
- if description is not None:
- request.description = description
+ if parent is not None:
+ request.parent = parent
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.snapshot_table,
- default_timeout=None,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.list_authorized_views
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -1186,86 +1529,106 @@ async def snapshot_table(
metadata=metadata,
)
- # Wrap the response in an operation future.
- response = operation_async.from_gapic(
- response,
- self._client._transport.operations_client,
- table.Snapshot,
- metadata_type=bigtable_table_admin.SnapshotTableMetadata,
+ # This method is paged; wrap the response in a pager, which provides
+ # an `__aiter__` convenience method.
+ response = pagers.ListAuthorizedViewsAsyncPager(
+ method=rpc,
+ request=request,
+ response=response,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
)
# Done; return the response.
return response
- async def get_snapshot(
+ async def get_authorized_view(
self,
- request: Union[bigtable_table_admin.GetSnapshotRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_table_admin.GetAuthorizedViewRequest, dict]
+ ] = None,
*,
- name: str = None,
+ name: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
- ) -> table.Snapshot:
- r"""Gets metadata information about the specified
- snapshot.
- Note: This is a private alpha release of Cloud Bigtable
- snapshots. This feature is not currently available to
- most Cloud Bigtable customers. This feature might be
- changed in backward-incompatible ways and is not
- recommended for production use. It is not subject to any
- SLA or deprecation policy.
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> table.AuthorizedView:
+ r"""Gets information from a specified AuthorizedView.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_get_authorized_view():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.GetAuthorizedViewRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ response = await client.get_authorized_view(request=request)
+
+ # Handle the response
+ print(response)
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.GetSnapshotRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.GetAuthorizedViewRequest, dict]]):
The request object. Request message for
- [google.bigtable.admin.v2.BigtableTableAdmin.GetSnapshot][google.bigtable.admin.v2.BigtableTableAdmin.GetSnapshot]
- Note: This is a private alpha release of Cloud Bigtable
- snapshots. This feature is not currently available to
- most Cloud Bigtable customers. This feature might be
- changed in backward-incompatible ways and is not
- recommended for production use. It is not subject to any
- SLA or deprecation policy.
+ [google.bigtable.admin.v2.BigtableTableAdmin.GetAuthorizedView][google.bigtable.admin.v2.BigtableTableAdmin.GetAuthorizedView]
name (:class:`str`):
- Required. The unique name of the requested snapshot.
- Values are of the form
- ``projects/{project}/instances/{instance}/clusters/{cluster}/snapshots/{snapshot}``.
+ Required. The unique name of the requested
+ AuthorizedView. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}/authorizedViews/{authorized_view}``.
This corresponds to the ``name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
- google.cloud.bigtable_admin_v2.types.Snapshot:
- A snapshot of a table at a particular
- time. A snapshot can be used as a
- checkpoint for data restoration or a
- data source for a new table.
- Note: This is a private alpha release of
- Cloud Bigtable snapshots. This feature
- is not currently available to most Cloud
- Bigtable customers. This feature might
- be changed in backward-incompatible ways
- and is not recommended for production
- use. It is not subject to any SLA or
- deprecation policy.
+ google.cloud.bigtable_admin_v2.types.AuthorizedView:
+ AuthorizedViews represent subsets of
+ a particular Cloud Bigtable table. Users
+ can configure access to each Authorized
+ View independently from the table and
+ use the existing Data APIs to access the
+ subset of data.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_table_admin.GetSnapshotRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.GetAuthorizedViewRequest):
+ request = bigtable_table_admin.GetAuthorizedViewRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
@@ -1274,21 +1637,9 @@ async def get_snapshot(
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.get_snapshot,
- default_retry=retries.Retry(
- initial=1.0,
- maximum=60.0,
- multiplier=2,
- predicate=retries.if_exception_type(
- core_exceptions.DeadlineExceeded,
- core_exceptions.ServiceUnavailable,
- ),
- deadline=60.0,
- ),
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.get_authorized_view
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -1296,6 +1647,9 @@ async def get_snapshot(
gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -1307,108 +1661,135 @@ async def get_snapshot(
# Done; return the response.
return response
- async def list_snapshots(
+ async def update_authorized_view(
self,
- request: Union[bigtable_table_admin.ListSnapshotsRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_table_admin.UpdateAuthorizedViewRequest, dict]
+ ] = None,
*,
- parent: str = None,
+ authorized_view: Optional[table.AuthorizedView] = None,
+ update_mask: Optional[field_mask_pb2.FieldMask] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
- ) -> pagers.ListSnapshotsAsyncPager:
- r"""Lists all snapshots associated with the specified
- cluster.
- Note: This is a private alpha release of Cloud Bigtable
- snapshots. This feature is not currently available to
- most Cloud Bigtable customers. This feature might be
- changed in backward-incompatible ways and is not
- recommended for production use. It is not subject to any
- SLA or deprecation policy.
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operation_async.AsyncOperation:
+ r"""Updates an AuthorizedView in a table.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_update_authorized_view():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.UpdateAuthorizedViewRequest(
+ )
+
+ # Make the request
+ operation = client.update_authorized_view(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = (await operation).result()
+
+ # Handle the response
+ print(response)
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.ListSnapshotsRequest, dict]):
- The request object. Request message for
- [google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots][google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots]
- Note: This is a private alpha release of Cloud Bigtable
- snapshots. This feature is not currently available to
- most Cloud Bigtable customers. This feature might be
- changed in backward-incompatible ways and is not
- recommended for production use. It is not subject to any
- SLA or deprecation policy.
- parent (:class:`str`):
- Required. The unique name of the cluster for which
- snapshots should be listed. Values are of the form
- ``projects/{project}/instances/{instance}/clusters/{cluster}``.
- Use ``{cluster} = '-'`` to list snapshots for all
- clusters in an instance, e.g.,
- ``projects/{project}/instances/{instance}/clusters/-``.
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.UpdateAuthorizedViewRequest, dict]]):
+ The request object. The request for
+ [UpdateAuthorizedView][google.bigtable.admin.v2.BigtableTableAdmin.UpdateAuthorizedView].
+ authorized_view (:class:`google.cloud.bigtable_admin_v2.types.AuthorizedView`):
+ Required. The AuthorizedView to update. The ``name`` in
+ ``authorized_view`` is used to identify the
+ AuthorizedView. AuthorizedView name must in this format:
+ ``projects/{project}/instances/{instance}/tables/{table}/authorizedViews/{authorized_view}``.
+
+ This corresponds to the ``authorized_view`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`):
+ Optional. The list of fields to update. A mask
+ specifying which fields in the AuthorizedView resource
+ should be updated. This mask is relative to the
+ AuthorizedView resource, not to the request message. A
+ field will be overwritten if it is in the mask. If
+ empty, all fields set in the request will be
+ overwritten. A special value ``*`` means to overwrite
+ all fields (including fields not set in the request).
- This corresponds to the ``parent`` field
+ This corresponds to the ``update_mask`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
- google.cloud.bigtable_admin_v2.services.bigtable_table_admin.pagers.ListSnapshotsAsyncPager:
- Response message for
- [google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots][google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots]
-
- Note: This is a private alpha release of Cloud
- Bigtable snapshots. This feature is not currently
- available to most Cloud Bigtable customers. This
- feature might be changed in backward-incompatible
- ways and is not recommended for production use. It is
- not subject to any SLA or deprecation policy.
+ google.api_core.operation_async.AsyncOperation:
+ An object representing a long-running operation.
- Iterating over this object will yield results and
- resolve additional pages automatically.
+ The result type for the operation will be :class:`google.cloud.bigtable_admin_v2.types.AuthorizedView` AuthorizedViews represent subsets of a particular Cloud Bigtable table. Users
+ can configure access to each Authorized View
+ independently from the table and use the existing
+ Data APIs to access the subset of data.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([parent])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [authorized_view, update_mask]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_table_admin.ListSnapshotsRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.UpdateAuthorizedViewRequest):
+ request = bigtable_table_admin.UpdateAuthorizedViewRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
- if parent is not None:
- request.parent = parent
+ if authorized_view is not None:
+ request.authorized_view = authorized_view
+ if update_mask is not None:
+ request.update_mask = update_mask
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.list_snapshots,
- default_retry=retries.Retry(
- initial=1.0,
- maximum=60.0,
- multiplier=2,
- predicate=retries.if_exception_type(
- core_exceptions.DeadlineExceeded,
- core_exceptions.ServiceUnavailable,
- ),
- deadline=60.0,
- ),
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.update_authorized_view
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ gapic_v1.routing_header.to_grpc_metadata(
+ (("authorized_view.name", request.authorized_view.name),)
+ ),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -1417,70 +1798,1654 @@ async def list_snapshots(
metadata=metadata,
)
- # This method is paged; wrap the response in a pager, which provides
- # an `__aiter__` convenience method.
- response = pagers.ListSnapshotsAsyncPager(
- method=rpc,
- request=request,
- response=response,
+ # Wrap the response in an operation future.
+ response = operation_async.from_gapic(
+ response,
+ self._client._transport.operations_client,
+ table.AuthorizedView,
+ metadata_type=bigtable_table_admin.UpdateAuthorizedViewMetadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ async def delete_authorized_view(
+ self,
+ request: Optional[
+ Union[bigtable_table_admin.DeleteAuthorizedViewRequest, dict]
+ ] = None,
+ *,
+ name: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> None:
+ r"""Permanently deletes a specified AuthorizedView.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_delete_authorized_view():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.DeleteAuthorizedViewRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ await client.delete_authorized_view(request=request)
+
+ Args:
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.DeleteAuthorizedViewRequest, dict]]):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.DeleteAuthorizedView][google.bigtable.admin.v2.BigtableTableAdmin.DeleteAuthorizedView]
+ name (:class:`str`):
+ Required. The unique name of the AuthorizedView to be
+ deleted. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}/authorizedViews/{authorized_view}``.
+
+ This corresponds to the ``name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.DeleteAuthorizedViewRequest):
+ request = bigtable_table_admin.DeleteAuthorizedViewRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.delete_authorized_view
+ ]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
+ # Send the request.
+ await rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ async def modify_column_families(
+ self,
+ request: Optional[
+ Union[bigtable_table_admin.ModifyColumnFamiliesRequest, dict]
+ ] = None,
+ *,
+ name: Optional[str] = None,
+ modifications: Optional[
+ MutableSequence[
+ bigtable_table_admin.ModifyColumnFamiliesRequest.Modification
+ ]
+ ] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> table.Table:
+ r"""Performs a series of column family modifications on
+ the specified table. Either all or none of the
+ modifications will occur before this method returns, but
+ data requests received prior to that point may see a
+ table where only some modifications have taken effect.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_modify_column_families():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.ModifyColumnFamiliesRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ response = await client.modify_column_families(request=request)
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.ModifyColumnFamiliesRequest, dict]]):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.ModifyColumnFamilies][google.bigtable.admin.v2.BigtableTableAdmin.ModifyColumnFamilies]
+ name (:class:`str`):
+ Required. The unique name of the table whose families
+ should be modified. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}``.
+
+ This corresponds to the ``name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ modifications (:class:`MutableSequence[google.cloud.bigtable_admin_v2.types.ModifyColumnFamiliesRequest.Modification]`):
+ Required. Modifications to be
+ atomically applied to the specified
+ table's families. Entries are applied in
+ order, meaning that earlier
+ modifications can be masked by later
+ ones (in the case of repeated updates to
+ the same family, for example).
+
+ This corresponds to the ``modifications`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.cloud.bigtable_admin_v2.types.Table:
+ A collection of user data indexed by
+ row, column, and timestamp. Each table
+ is served using the resources of its
+ parent cluster.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name, modifications]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.ModifyColumnFamiliesRequest):
+ request = bigtable_table_admin.ModifyColumnFamiliesRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if name is not None:
+ request.name = name
+ if modifications:
+ request.modifications.extend(modifications)
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.modify_column_families
+ ]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
+ # Send the request.
+ response = await rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ async def drop_row_range(
+ self,
+ request: Optional[Union[bigtable_table_admin.DropRowRangeRequest, dict]] = None,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> None:
+ r"""Permanently drop/delete a row range from a specified
+ table. The request can specify whether to delete all
+ rows in a table, or only those that match a particular
+ prefix.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_drop_row_range():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.DropRowRangeRequest(
+ row_key_prefix=b'row_key_prefix_blob',
+ name="name_value",
+ )
+
+ # Make the request
+ await client.drop_row_range(request=request)
+
+ Args:
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.DropRowRangeRequest, dict]]):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.DropRowRange][google.bigtable.admin.v2.BigtableTableAdmin.DropRowRange]
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+ """
+ # Create or coerce a protobuf request object.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.DropRowRangeRequest):
+ request = bigtable_table_admin.DropRowRangeRequest(request)
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.drop_row_range
+ ]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
+ # Send the request.
+ await rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ async def generate_consistency_token(
+ self,
+ request: Optional[
+ Union[bigtable_table_admin.GenerateConsistencyTokenRequest, dict]
+ ] = None,
+ *,
+ name: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> bigtable_table_admin.GenerateConsistencyTokenResponse:
+ r"""Generates a consistency token for a Table, which can
+ be used in CheckConsistency to check whether mutations
+ to the table that finished before this call started have
+ been replicated. The tokens will be available for 90
+ days.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_generate_consistency_token():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.GenerateConsistencyTokenRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ response = await client.generate_consistency_token(request=request)
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.GenerateConsistencyTokenRequest, dict]]):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken][google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken]
+ name (:class:`str`):
+ Required. The unique name of the Table for which to
+ create a consistency token. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}``.
+
+ This corresponds to the ``name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.cloud.bigtable_admin_v2.types.GenerateConsistencyTokenResponse:
+ Response message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken][google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken]
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(
+ request, bigtable_table_admin.GenerateConsistencyTokenRequest
+ ):
+ request = bigtable_table_admin.GenerateConsistencyTokenRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.generate_consistency_token
+ ]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
+ # Send the request.
+ response = await rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ async def check_consistency(
+ self,
+ request: Optional[
+ Union[bigtable_table_admin.CheckConsistencyRequest, dict]
+ ] = None,
+ *,
+ name: Optional[str] = None,
+ consistency_token: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> bigtable_table_admin.CheckConsistencyResponse:
+ r"""Checks replication consistency based on a consistency
+ token, that is, if replication has caught up based on
+ the conditions specified in the token and the check
+ request.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_check_consistency():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.CheckConsistencyRequest(
+ name="name_value",
+ consistency_token="consistency_token_value",
+ )
+
+ # Make the request
+ response = await client.check_consistency(request=request)
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.CheckConsistencyRequest, dict]]):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency][google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency]
+ name (:class:`str`):
+ Required. The unique name of the Table for which to
+ check replication consistency. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}``.
+
+ This corresponds to the ``name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ consistency_token (:class:`str`):
+ Required. The token created using
+ GenerateConsistencyToken for the Table.
+
+ This corresponds to the ``consistency_token`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.cloud.bigtable_admin_v2.types.CheckConsistencyResponse:
+ Response message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency][google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency]
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name, consistency_token]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.CheckConsistencyRequest):
+ request = bigtable_table_admin.CheckConsistencyRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if name is not None:
+ request.name = name
+ if consistency_token is not None:
+ request.consistency_token = consistency_token
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.check_consistency
+ ]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
+ # Send the request.
+ response = await rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ async def snapshot_table(
+ self,
+ request: Optional[
+ Union[bigtable_table_admin.SnapshotTableRequest, dict]
+ ] = None,
+ *,
+ name: Optional[str] = None,
+ cluster: Optional[str] = None,
+ snapshot_id: Optional[str] = None,
+ description: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operation_async.AsyncOperation:
+ r"""Creates a new snapshot in the specified cluster from
+ the specified source table. The cluster and the table
+ must be in the same instance.
+
+ Note: This is a private alpha release of Cloud Bigtable
+ snapshots. This feature is not currently available to
+ most Cloud Bigtable customers. This feature might be
+ changed in backward-incompatible ways and is not
+ recommended for production use. It is not subject to any
+ SLA or deprecation policy.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_snapshot_table():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.SnapshotTableRequest(
+ name="name_value",
+ cluster="cluster_value",
+ snapshot_id="snapshot_id_value",
+ )
+
+ # Make the request
+ operation = client.snapshot_table(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = (await operation).result()
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.SnapshotTableRequest, dict]]):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.SnapshotTable][google.bigtable.admin.v2.BigtableTableAdmin.SnapshotTable]
+
+ Note: This is a private alpha release of Cloud Bigtable
+ snapshots. This feature is not currently available to
+ most Cloud Bigtable customers. This feature might be
+ changed in backward-incompatible ways and is not
+ recommended for production use. It is not subject to any
+ SLA or deprecation policy.
+ name (:class:`str`):
+ Required. The unique name of the table to have the
+ snapshot taken. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}``.
+
+ This corresponds to the ``name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ cluster (:class:`str`):
+ Required. The name of the cluster where the snapshot
+ will be created in. Values are of the form
+ ``projects/{project}/instances/{instance}/clusters/{cluster}``.
+
+ This corresponds to the ``cluster`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ snapshot_id (:class:`str`):
+ Required. The ID by which the new snapshot should be
+ referred to within the parent cluster, e.g.,
+ ``mysnapshot`` of the form:
+ ``[_a-zA-Z0-9][-_.a-zA-Z0-9]*`` rather than
+ ``projects/{project}/instances/{instance}/clusters/{cluster}/snapshots/mysnapshot``.
+
+ This corresponds to the ``snapshot_id`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ description (:class:`str`):
+ Description of the snapshot.
+ This corresponds to the ``description`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.api_core.operation_async.AsyncOperation:
+ An object representing a long-running operation.
+
+ The result type for the operation will be :class:`google.cloud.bigtable_admin_v2.types.Snapshot` A snapshot of a table at a particular time. A snapshot can be used as a
+ checkpoint for data restoration or a data source for
+ a new table.
+
+ Note: This is a private alpha release of Cloud
+ Bigtable snapshots. This feature is not currently
+ available to most Cloud Bigtable customers. This
+ feature might be changed in backward-incompatible
+ ways and is not recommended for production use. It is
+ not subject to any SLA or deprecation policy.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name, cluster, snapshot_id, description]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.SnapshotTableRequest):
+ request = bigtable_table_admin.SnapshotTableRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if name is not None:
+ request.name = name
+ if cluster is not None:
+ request.cluster = cluster
+ if snapshot_id is not None:
+ request.snapshot_id = snapshot_id
+ if description is not None:
+ request.description = description
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.snapshot_table
+ ]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
+ # Send the request.
+ response = await rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Wrap the response in an operation future.
+ response = operation_async.from_gapic(
+ response,
+ self._client._transport.operations_client,
+ table.Snapshot,
+ metadata_type=bigtable_table_admin.SnapshotTableMetadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ async def get_snapshot(
+ self,
+ request: Optional[Union[bigtable_table_admin.GetSnapshotRequest, dict]] = None,
+ *,
+ name: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> table.Snapshot:
+ r"""Gets metadata information about the specified
+ snapshot.
+ Note: This is a private alpha release of Cloud Bigtable
+ snapshots. This feature is not currently available to
+ most Cloud Bigtable customers. This feature might be
+ changed in backward-incompatible ways and is not
+ recommended for production use. It is not subject to any
+ SLA or deprecation policy.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_get_snapshot():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.GetSnapshotRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ response = await client.get_snapshot(request=request)
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.GetSnapshotRequest, dict]]):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.GetSnapshot][google.bigtable.admin.v2.BigtableTableAdmin.GetSnapshot]
+
+ Note: This is a private alpha release of Cloud Bigtable
+ snapshots. This feature is not currently available to
+ most Cloud Bigtable customers. This feature might be
+ changed in backward-incompatible ways and is not
+ recommended for production use. It is not subject to any
+ SLA or deprecation policy.
+ name (:class:`str`):
+ Required. The unique name of the requested snapshot.
+ Values are of the form
+ ``projects/{project}/instances/{instance}/clusters/{cluster}/snapshots/{snapshot}``.
+
+ This corresponds to the ``name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.cloud.bigtable_admin_v2.types.Snapshot:
+ A snapshot of a table at a particular
+ time. A snapshot can be used as a
+ checkpoint for data restoration or a
+ data source for a new table.
+
+ Note: This is a private alpha release of
+ Cloud Bigtable snapshots. This feature
+ is not currently available to most Cloud
+ Bigtable customers. This feature might
+ be changed in backward-incompatible ways
+ and is not recommended for production
+ use. It is not subject to any SLA or
+ deprecation policy.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.GetSnapshotRequest):
+ request = bigtable_table_admin.GetSnapshotRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.get_snapshot
+ ]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
+ # Send the request.
+ response = await rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ async def list_snapshots(
+ self,
+ request: Optional[
+ Union[bigtable_table_admin.ListSnapshotsRequest, dict]
+ ] = None,
+ *,
+ parent: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> pagers.ListSnapshotsAsyncPager:
+ r"""Lists all snapshots associated with the specified
+ cluster.
+ Note: This is a private alpha release of Cloud Bigtable
+ snapshots. This feature is not currently available to
+ most Cloud Bigtable customers. This feature might be
+ changed in backward-incompatible ways and is not
+ recommended for production use. It is not subject to any
+ SLA or deprecation policy.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_list_snapshots():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.ListSnapshotsRequest(
+ parent="parent_value",
+ )
+
+ # Make the request
+ page_result = client.list_snapshots(request=request)
+
+ # Handle the response
+ async for response in page_result:
+ print(response)
+
+ Args:
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.ListSnapshotsRequest, dict]]):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots][google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots]
+
+ Note: This is a private alpha release of Cloud Bigtable
+ snapshots. This feature is not currently available to
+ most Cloud Bigtable customers. This feature might be
+ changed in backward-incompatible ways and is not
+ recommended for production use. It is not subject to any
+ SLA or deprecation policy.
+ parent (:class:`str`):
+ Required. The unique name of the cluster for which
+ snapshots should be listed. Values are of the form
+ ``projects/{project}/instances/{instance}/clusters/{cluster}``.
+ Use ``{cluster} = '-'`` to list snapshots for all
+ clusters in an instance, e.g.,
+ ``projects/{project}/instances/{instance}/clusters/-``.
+
+ This corresponds to the ``parent`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.cloud.bigtable_admin_v2.services.bigtable_table_admin.pagers.ListSnapshotsAsyncPager:
+ Response message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots][google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots]
+
+ Note: This is a private alpha release of Cloud
+ Bigtable snapshots. This feature is not currently
+ available to most Cloud Bigtable customers. This
+ feature might be changed in backward-incompatible
+ ways and is not recommended for production use. It is
+ not subject to any SLA or deprecation policy.
+
+ Iterating over this object will yield results and
+ resolve additional pages automatically.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.ListSnapshotsRequest):
+ request = bigtable_table_admin.ListSnapshotsRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if parent is not None:
+ request.parent = parent
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.list_snapshots
+ ]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
+ # Send the request.
+ response = await rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # This method is paged; wrap the response in a pager, which provides
+ # an `__aiter__` convenience method.
+ response = pagers.ListSnapshotsAsyncPager(
+ method=rpc,
+ request=request,
+ response=response,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ async def delete_snapshot(
+ self,
+ request: Optional[
+ Union[bigtable_table_admin.DeleteSnapshotRequest, dict]
+ ] = None,
+ *,
+ name: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> None:
+ r"""Permanently deletes the specified snapshot.
+
+ Note: This is a private alpha release of Cloud Bigtable
+ snapshots. This feature is not currently available to
+ most Cloud Bigtable customers. This feature might be
+ changed in backward-incompatible ways and is not
+ recommended for production use. It is not subject to any
+ SLA or deprecation policy.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_delete_snapshot():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.DeleteSnapshotRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ await client.delete_snapshot(request=request)
+
+ Args:
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.DeleteSnapshotRequest, dict]]):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.DeleteSnapshot][google.bigtable.admin.v2.BigtableTableAdmin.DeleteSnapshot]
+
+ Note: This is a private alpha release of Cloud Bigtable
+ snapshots. This feature is not currently available to
+ most Cloud Bigtable customers. This feature might be
+ changed in backward-incompatible ways and is not
+ recommended for production use. It is not subject to any
+ SLA or deprecation policy.
+ name (:class:`str`):
+ Required. The unique name of the snapshot to be deleted.
+ Values are of the form
+ ``projects/{project}/instances/{instance}/clusters/{cluster}/snapshots/{snapshot}``.
+
+ This corresponds to the ``name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.DeleteSnapshotRequest):
+ request = bigtable_table_admin.DeleteSnapshotRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.delete_snapshot
+ ]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
+ # Send the request.
+ await rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ async def create_backup(
+ self,
+ request: Optional[Union[bigtable_table_admin.CreateBackupRequest, dict]] = None,
+ *,
+ parent: Optional[str] = None,
+ backup_id: Optional[str] = None,
+ backup: Optional[table.Backup] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operation_async.AsyncOperation:
+ r"""Starts creating a new Cloud Bigtable Backup. The returned backup
+ [long-running operation][google.longrunning.Operation] can be
+ used to track creation of the backup. The
+ [metadata][google.longrunning.Operation.metadata] field type is
+ [CreateBackupMetadata][google.bigtable.admin.v2.CreateBackupMetadata].
+ The [response][google.longrunning.Operation.response] field type
+ is [Backup][google.bigtable.admin.v2.Backup], if successful.
+ Cancelling the returned operation will stop the creation and
+ delete the backup.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_create_backup():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ backup = bigtable_admin_v2.Backup()
+ backup.source_table = "source_table_value"
+
+ request = bigtable_admin_v2.CreateBackupRequest(
+ parent="parent_value",
+ backup_id="backup_id_value",
+ backup=backup,
+ )
+
+ # Make the request
+ operation = client.create_backup(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = (await operation).result()
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.CreateBackupRequest, dict]]):
+ The request object. The request for
+ [CreateBackup][google.bigtable.admin.v2.BigtableTableAdmin.CreateBackup].
+ parent (:class:`str`):
+ Required. This must be one of the clusters in the
+ instance in which this table is located. The backup will
+ be stored in this cluster. Values are of the form
+ ``projects/{project}/instances/{instance}/clusters/{cluster}``.
+
+ This corresponds to the ``parent`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ backup_id (:class:`str`):
+ Required. The id of the backup to be created. The
+ ``backup_id`` along with the parent ``parent`` are
+ combined as {parent}/backups/{backup_id} to create the
+ full backup name, of the form:
+ ``projects/{project}/instances/{instance}/clusters/{cluster}/backups/{backup_id}``.
+ This string must be between 1 and 50 characters in
+ length and match the regex [*a-zA-Z0-9][-*.a-zA-Z0-9]\*.
+
+ This corresponds to the ``backup_id`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ backup (:class:`google.cloud.bigtable_admin_v2.types.Backup`):
+ Required. The backup to create.
+ This corresponds to the ``backup`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.api_core.operation_async.AsyncOperation:
+ An object representing a long-running operation.
+
+ The result type for the operation will be
+ :class:`google.cloud.bigtable_admin_v2.types.Backup` A
+ backup of a Cloud Bigtable table.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent, backup_id, backup]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.CreateBackupRequest):
+ request = bigtable_table_admin.CreateBackupRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if parent is not None:
+ request.parent = parent
+ if backup_id is not None:
+ request.backup_id = backup_id
+ if backup is not None:
+ request.backup = backup
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.create_backup
+ ]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
+ # Send the request.
+ response = await rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Wrap the response in an operation future.
+ response = operation_async.from_gapic(
+ response,
+ self._client._transport.operations_client,
+ table.Backup,
+ metadata_type=bigtable_table_admin.CreateBackupMetadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ async def get_backup(
+ self,
+ request: Optional[Union[bigtable_table_admin.GetBackupRequest, dict]] = None,
+ *,
+ name: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> table.Backup:
+ r"""Gets metadata on a pending or completed Cloud
+ Bigtable Backup.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_get_backup():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.GetBackupRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ response = await client.get_backup(request=request)
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.GetBackupRequest, dict]]):
+ The request object. The request for
+ [GetBackup][google.bigtable.admin.v2.BigtableTableAdmin.GetBackup].
+ name (:class:`str`):
+ Required. Name of the backup. Values are of the form
+ ``projects/{project}/instances/{instance}/clusters/{cluster}/backups/{backup}``.
+
+ This corresponds to the ``name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.cloud.bigtable_admin_v2.types.Backup:
+ A backup of a Cloud Bigtable table.
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.GetBackupRequest):
+ request = bigtable_table_admin.GetBackupRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.get_backup
+ ]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
+ # Send the request.
+ response = await rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ async def update_backup(
+ self,
+ request: Optional[Union[bigtable_table_admin.UpdateBackupRequest, dict]] = None,
+ *,
+ backup: Optional[table.Backup] = None,
+ update_mask: Optional[field_mask_pb2.FieldMask] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> table.Backup:
+ r"""Updates a pending or completed Cloud Bigtable Backup.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_update_backup():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ backup = bigtable_admin_v2.Backup()
+ backup.source_table = "source_table_value"
+
+ request = bigtable_admin_v2.UpdateBackupRequest(
+ backup=backup,
+ )
+
+ # Make the request
+ response = await client.update_backup(request=request)
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.UpdateBackupRequest, dict]]):
+ The request object. The request for
+ [UpdateBackup][google.bigtable.admin.v2.BigtableTableAdmin.UpdateBackup].
+ backup (:class:`google.cloud.bigtable_admin_v2.types.Backup`):
+ Required. The backup to update. ``backup.name``, and the
+ fields to be updated as specified by ``update_mask`` are
+ required. Other fields are ignored. Update is only
+ supported for the following fields:
+
+ - ``backup.expire_time``.
+
+ This corresponds to the ``backup`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`):
+ Required. A mask specifying which fields (e.g.
+ ``expire_time``) in the Backup resource should be
+ updated. This mask is relative to the Backup resource,
+ not to the request message. The field mask must always
+ be specified; this prevents any future fields from being
+ erased accidentally by clients that do not know about
+ them.
+
+ This corresponds to the ``update_mask`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.cloud.bigtable_admin_v2.types.Backup:
+ A backup of a Cloud Bigtable table.
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [backup, update_mask]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.UpdateBackupRequest):
+ request = bigtable_table_admin.UpdateBackupRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if backup is not None:
+ request.backup = backup
+ if update_mask is not None:
+ request.update_mask = update_mask
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.update_backup
+ ]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata(
+ (("backup.name", request.backup.name),)
+ ),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
+ # Send the request.
+ response = await rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
metadata=metadata,
)
# Done; return the response.
return response
- async def delete_snapshot(
+ async def delete_backup(
self,
- request: Union[bigtable_table_admin.DeleteSnapshotRequest, dict] = None,
+ request: Optional[Union[bigtable_table_admin.DeleteBackupRequest, dict]] = None,
*,
- name: str = None,
+ name: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> None:
- r"""Permanently deletes the specified snapshot.
- Note: This is a private alpha release of Cloud Bigtable
- snapshots. This feature is not currently available to
- most Cloud Bigtable customers. This feature might be
- changed in backward-incompatible ways and is not
- recommended for production use. It is not subject to any
- SLA or deprecation policy.
+ r"""Deletes a pending or completed Cloud Bigtable backup.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_delete_backup():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.DeleteBackupRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ await client.delete_backup(request=request)
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.DeleteSnapshotRequest, dict]):
- The request object. Request message for
- [google.bigtable.admin.v2.BigtableTableAdmin.DeleteSnapshot][google.bigtable.admin.v2.BigtableTableAdmin.DeleteSnapshot]
- Note: This is a private alpha release of Cloud Bigtable
- snapshots. This feature is not currently available to
- most Cloud Bigtable customers. This feature might be
- changed in backward-incompatible ways and is not
- recommended for production use. It is not subject to any
- SLA or deprecation policy.
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.DeleteBackupRequest, dict]]):
+ The request object. The request for
+ [DeleteBackup][google.bigtable.admin.v2.BigtableTableAdmin.DeleteBackup].
name (:class:`str`):
- Required. The unique name of the snapshot to be deleted.
- Values are of the form
- ``projects/{project}/instances/{instance}/clusters/{cluster}/snapshots/{snapshot}``.
+ Required. Name of the backup to delete. Values are of
+ the form
+ ``projects/{project}/instances/{instance}/clusters/{cluster}/backups/{backup}``.
This corresponds to the ``name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_table_admin.DeleteSnapshotRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.DeleteBackupRequest):
+ request = bigtable_table_admin.DeleteBackupRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
@@ -1489,11 +3454,9 @@ async def delete_snapshot(
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.delete_snapshot,
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.delete_backup
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -1501,6 +3464,9 @@ async def delete_snapshot(
gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
await rpc(
request,
@@ -1509,62 +3475,350 @@ async def delete_snapshot(
metadata=metadata,
)
- async def create_backup(
+ async def list_backups(
+ self,
+ request: Optional[Union[bigtable_table_admin.ListBackupsRequest, dict]] = None,
+ *,
+ parent: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> pagers.ListBackupsAsyncPager:
+ r"""Lists Cloud Bigtable backups. Returns both completed
+ and pending backups.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_list_backups():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.ListBackupsRequest(
+ parent="parent_value",
+ )
+
+ # Make the request
+ page_result = client.list_backups(request=request)
+
+ # Handle the response
+ async for response in page_result:
+ print(response)
+
+ Args:
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.ListBackupsRequest, dict]]):
+ The request object. The request for
+ [ListBackups][google.bigtable.admin.v2.BigtableTableAdmin.ListBackups].
+ parent (:class:`str`):
+ Required. The cluster to list backups from. Values are
+ of the form
+ ``projects/{project}/instances/{instance}/clusters/{cluster}``.
+ Use ``{cluster} = '-'`` to list backups for all clusters
+ in an instance, e.g.,
+ ``projects/{project}/instances/{instance}/clusters/-``.
+
+ This corresponds to the ``parent`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.cloud.bigtable_admin_v2.services.bigtable_table_admin.pagers.ListBackupsAsyncPager:
+ The response for
+ [ListBackups][google.bigtable.admin.v2.BigtableTableAdmin.ListBackups].
+
+ Iterating over this object will yield results and
+ resolve additional pages automatically.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.ListBackupsRequest):
+ request = bigtable_table_admin.ListBackupsRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if parent is not None:
+ request.parent = parent
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.list_backups
+ ]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
+ # Send the request.
+ response = await rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # This method is paged; wrap the response in a pager, which provides
+ # an `__aiter__` convenience method.
+ response = pagers.ListBackupsAsyncPager(
+ method=rpc,
+ request=request,
+ response=response,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ async def _restore_table(
self,
- request: Union[bigtable_table_admin.CreateBackupRequest, dict] = None,
+ request: Optional[Union[bigtable_table_admin.RestoreTableRequest, dict]] = None,
*,
- parent: str = None,
- backup_id: str = None,
- backup: table.Backup = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> operation_async.AsyncOperation:
- r"""Starts creating a new Cloud Bigtable Backup. The returned backup
- [long-running operation][google.longrunning.Operation] can be
- used to track creation of the backup. The
+ r"""Create a new table by restoring from a completed backup. The
+ returned table [long-running
+ operation][google.longrunning.Operation] can be used to track
+ the progress of the operation, and to cancel it. The
[metadata][google.longrunning.Operation.metadata] field type is
- [CreateBackupMetadata][google.bigtable.admin.v2.CreateBackupMetadata].
- The [response][google.longrunning.Operation.response] field type
- is [Backup][google.bigtable.admin.v2.Backup], if successful.
- Cancelling the returned operation will stop the creation and
- delete the backup.
+ [RestoreTableMetadata][google.bigtable.admin.v2.RestoreTableMetadata].
+ The [response][google.longrunning.Operation.response] type is
+ [Table][google.bigtable.admin.v2.Table], if successful.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_restore_table():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.RestoreTableRequest(
+ backup="backup_value",
+ parent="parent_value",
+ table_id="table_id_value",
+ )
+
+ # Make the request
+ operation = client._restore_table(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = (await operation).result()
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.RestoreTableRequest, dict]]):
+ The request object. The request for
+ [RestoreTable][google.bigtable.admin.v2.BigtableTableAdmin.RestoreTable].
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.api_core.operation_async.AsyncOperation:
+ An object representing a long-running operation.
+
+ The result type for the operation will be :class:`google.cloud.bigtable_admin_v2.types.Table` A collection of user data indexed by row, column, and timestamp.
+ Each table is served using the resources of its
+ parent cluster.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.RestoreTableRequest):
+ request = bigtable_table_admin.RestoreTableRequest(request)
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.restore_table
+ ]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
+ # Send the request.
+ response = await rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Wrap the response in an operation future.
+ response = operation_async.from_gapic(
+ response,
+ self._client._transport.operations_client,
+ table.Table,
+ metadata_type=bigtable_table_admin.RestoreTableMetadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ async def copy_backup(
+ self,
+ request: Optional[Union[bigtable_table_admin.CopyBackupRequest, dict]] = None,
+ *,
+ parent: Optional[str] = None,
+ backup_id: Optional[str] = None,
+ source_backup: Optional[str] = None,
+ expire_time: Optional[timestamp_pb2.Timestamp] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operation_async.AsyncOperation:
+ r"""Copy a Cloud Bigtable backup to a new backup in the
+ destination cluster located in the destination instance
+ and project.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_copy_backup():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.CopyBackupRequest(
+ parent="parent_value",
+ backup_id="backup_id_value",
+ source_backup="source_backup_value",
+ )
+
+ # Make the request
+ operation = client.copy_backup(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = (await operation).result()
+
+ # Handle the response
+ print(response)
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.CreateBackupRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.CopyBackupRequest, dict]]):
The request object. The request for
- [CreateBackup][google.bigtable.admin.v2.BigtableTableAdmin.CreateBackup].
+ [CopyBackup][google.bigtable.admin.v2.BigtableTableAdmin.CopyBackup].
parent (:class:`str`):
- Required. This must be one of the clusters in the
- instance in which this table is located. The backup will
- be stored in this cluster. Values are of the form
+ Required. The name of the destination cluster that will
+ contain the backup copy. The cluster must already exist.
+ Values are of the form:
``projects/{project}/instances/{instance}/clusters/{cluster}``.
This corresponds to the ``parent`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
backup_id (:class:`str`):
- Required. The id of the backup to be created. The
- ``backup_id`` along with the parent ``parent`` are
- combined as {parent}/backups/{backup_id} to create the
- full backup name, of the form:
+ Required. The id of the new backup. The ``backup_id``
+ along with ``parent`` are combined as
+ {parent}/backups/{backup_id} to create the full backup
+ name, of the form:
``projects/{project}/instances/{instance}/clusters/{cluster}/backups/{backup_id}``.
This string must be between 1 and 50 characters in
- length and match the regex [*a-zA-Z0-9][-*.a-zA-Z0-9]*.
+ length and match the regex [*a-zA-Z0-9][-*.a-zA-Z0-9]\*.
This corresponds to the ``backup_id`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- backup (:class:`google.cloud.bigtable_admin_v2.types.Backup`):
- Required. The backup to create.
- This corresponds to the ``backup`` field
+ source_backup (:class:`str`):
+ Required. The source backup to be copied from. The
+ source backup needs to be in READY state for it to be
+ copied. Copying a copied backup is not allowed. Once
+ CopyBackup is in progress, the source backup cannot be
+ deleted or cleaned up on expiration until CopyBackup is
+ finished. Values are of the form:
+ ``projects//instances//clusters//backups/``.
+
+ This corresponds to the ``source_backup`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ expire_time (:class:`google.protobuf.timestamp_pb2.Timestamp`):
+ Required. Required. The expiration time of the copied
+ backup with microsecond granularity that must be at
+ least 6 hours and at most 30 days from the time the
+ request is received. Once the ``expire_time`` has
+ passed, Cloud Bigtable will delete the backup and free
+ the resources used by the backup.
+
+ This corresponds to the ``expire_time`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.api_core.operation_async.AsyncOperation:
@@ -1576,16 +3830,22 @@ async def create_backup(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([parent, backup_id, backup])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent, backup_id, source_backup, expire_time]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_table_admin.CreateBackupRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.CopyBackupRequest):
+ request = bigtable_table_admin.CopyBackupRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
@@ -1593,16 +3853,16 @@ async def create_backup(
request.parent = parent
if backup_id is not None:
request.backup_id = backup_id
- if backup is not None:
- request.backup = backup
+ if source_backup is not None:
+ request.source_backup = source_backup
+ if expire_time is not None:
+ request.expire_time = expire_time
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.create_backup,
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.copy_backup
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -1610,6 +3870,9 @@ async def create_backup(
gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -1623,86 +3886,141 @@ async def create_backup(
response,
self._client._transport.operations_client,
table.Backup,
- metadata_type=bigtable_table_admin.CreateBackupMetadata,
+ metadata_type=bigtable_table_admin.CopyBackupMetadata,
)
# Done; return the response.
return response
- async def get_backup(
+ async def get_iam_policy(
self,
- request: Union[bigtable_table_admin.GetBackupRequest, dict] = None,
+ request: Optional[Union[iam_policy_pb2.GetIamPolicyRequest, dict]] = None,
*,
- name: str = None,
+ resource: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
- ) -> table.Backup:
- r"""Gets metadata on a pending or completed Cloud
- Bigtable Backup.
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> policy_pb2.Policy:
+ r"""Gets the access control policy for a Bigtable
+ resource. Returns an empty policy if the resource exists
+ but does not have a policy set.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+ from google.iam.v1 import iam_policy_pb2 # type: ignore
+
+ async def sample_get_iam_policy():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = iam_policy_pb2.GetIamPolicyRequest(
+ resource="resource_value",
+ )
+
+ # Make the request
+ response = await client.get_iam_policy(request=request)
+
+ # Handle the response
+ print(response)
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.GetBackupRequest, dict]):
- The request object. The request for
- [GetBackup][google.bigtable.admin.v2.BigtableTableAdmin.GetBackup].
- name (:class:`str`):
- Required. Name of the backup. Values are of the form
- ``projects/{project}/instances/{instance}/clusters/{cluster}/backups/{backup}``.
+ request (Optional[Union[google.iam.v1.iam_policy_pb2.GetIamPolicyRequest, dict]]):
+ The request object. Request message for ``GetIamPolicy`` method.
+ resource (:class:`str`):
+ REQUIRED: The resource for which the
+ policy is being requested. See the
+ operation documentation for the
+ appropriate value for this field.
- This corresponds to the ``name`` field
+ This corresponds to the ``resource`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
- google.cloud.bigtable_admin_v2.types.Backup:
- A backup of a Cloud Bigtable table.
+ google.iam.v1.policy_pb2.Policy:
+ An Identity and Access Management (IAM) policy, which specifies access
+ controls for Google Cloud resources.
+
+ A Policy is a collection of bindings. A binding binds
+ one or more members, or principals, to a single role.
+ Principals can be user accounts, service accounts,
+ Google groups, and domains (such as G Suite). A role
+ is a named list of permissions; each role can be an
+ IAM predefined role or a user-created custom role.
+
+ For some types of Google Cloud resources, a binding
+ can also specify a condition, which is a logical
+ expression that allows access to a resource only if
+ the expression evaluates to true. A condition can add
+ constraints based on attributes of the request, the
+ resource, or both. To learn which resources support
+ conditions in their IAM policies, see the [IAM
+ documentation](https://cloud.google.com/iam/help/conditions/resource-policies).
+
+ **JSON example:**
+
+ :literal:`` { "bindings": [ { "role": "roles/resourcemanager.organizationAdmin", "members": [ "user:mike@example.com", "group:admins@example.com", "domain:google.com", "serviceAccount:my-project-id@appspot.gserviceaccount.com" ] }, { "role": "roles/resourcemanager.organizationViewer", "members": [ "user:eve@example.com" ], "condition": { "title": "expirable access", "description": "Does not grant access after Sep 2020", "expression": "request.time < timestamp('2020-10-01T00:00:00.000Z')", } } ], "etag": "BwWWja0YfJA=", "version": 3 }`\ \`
+
+ **YAML example:**
+
+ :literal:`` bindings: - members: - user:mike@example.com - group:admins@example.com - domain:google.com - serviceAccount:my-project-id@appspot.gserviceaccount.com role: roles/resourcemanager.organizationAdmin - members: - user:eve@example.com role: roles/resourcemanager.organizationViewer condition: title: expirable access description: Does not grant access after Sep 2020 expression: request.time < timestamp('2020-10-01T00:00:00.000Z') etag: BwWWja0YfJA= version: 3`\ \`
+
+ For a description of IAM and its features, see the
+ [IAM
+ documentation](https://cloud.google.com/iam/docs/).
+
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [resource]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_table_admin.GetBackupRequest(request)
-
- # If we have keyword arguments corresponding to fields on the
- # request, apply these.
- if name is not None:
- request.name = name
+ # - The request isn't a proto-plus wrapped type,
+ # so it must be constructed via keyword expansion.
+ if isinstance(request, dict):
+ request = iam_policy_pb2.GetIamPolicyRequest(**request)
+ elif not request:
+ request = iam_policy_pb2.GetIamPolicyRequest(resource=resource)
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.get_backup,
- default_retry=retries.Retry(
- initial=1.0,
- maximum=60.0,
- multiplier=2,
- predicate=retries.if_exception_type(
- core_exceptions.DeadlineExceeded,
- core_exceptions.ServiceUnavailable,
- ),
- deadline=60.0,
- ),
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.get_iam_policy
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ gapic_v1.routing_header.to_grpc_metadata((("resource", request.resource),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -1714,90 +4032,134 @@ async def get_backup(
# Done; return the response.
return response
- async def update_backup(
+ async def set_iam_policy(
self,
- request: Union[bigtable_table_admin.UpdateBackupRequest, dict] = None,
+ request: Optional[Union[iam_policy_pb2.SetIamPolicyRequest, dict]] = None,
*,
- backup: table.Backup = None,
- update_mask: field_mask_pb2.FieldMask = None,
+ resource: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
- ) -> table.Backup:
- r"""Updates a pending or completed Cloud Bigtable Backup.
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> policy_pb2.Policy:
+ r"""Sets the access control policy on a Bigtable
+ resource. Replaces any existing policy.
- Args:
- request (Union[google.cloud.bigtable_admin_v2.types.UpdateBackupRequest, dict]):
- The request object. The request for
- [UpdateBackup][google.bigtable.admin.v2.BigtableTableAdmin.UpdateBackup].
- backup (:class:`google.cloud.bigtable_admin_v2.types.Backup`):
- Required. The backup to update. ``backup.name``, and the
- fields to be updated as specified by ``update_mask`` are
- required. Other fields are ignored. Update is only
- supported for the following fields:
+ .. code-block:: python
- - ``backup.expire_time``.
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+ from google.iam.v1 import iam_policy_pb2 # type: ignore
- This corresponds to the ``backup`` field
- on the ``request`` instance; if ``request`` is provided, this
- should not be set.
- update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`):
- Required. A mask specifying which fields (e.g.
- ``expire_time``) in the Backup resource should be
- updated. This mask is relative to the Backup resource,
- not to the request message. The field mask must always
- be specified; this prevents any future fields from being
- erased accidentally by clients that do not know about
- them.
+ async def sample_set_iam_policy():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
- This corresponds to the ``update_mask`` field
+ # Initialize request argument(s)
+ request = iam_policy_pb2.SetIamPolicyRequest(
+ resource="resource_value",
+ )
+
+ # Make the request
+ response = await client.set_iam_policy(request=request)
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Optional[Union[google.iam.v1.iam_policy_pb2.SetIamPolicyRequest, dict]]):
+ The request object. Request message for ``SetIamPolicy`` method.
+ resource (:class:`str`):
+ REQUIRED: The resource for which the
+ policy is being specified. See the
+ operation documentation for the
+ appropriate value for this field.
+
+ This corresponds to the ``resource`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
- google.cloud.bigtable_admin_v2.types.Backup:
- A backup of a Cloud Bigtable table.
+ google.iam.v1.policy_pb2.Policy:
+ An Identity and Access Management (IAM) policy, which specifies access
+ controls for Google Cloud resources.
+
+ A Policy is a collection of bindings. A binding binds
+ one or more members, or principals, to a single role.
+ Principals can be user accounts, service accounts,
+ Google groups, and domains (such as G Suite). A role
+ is a named list of permissions; each role can be an
+ IAM predefined role or a user-created custom role.
+
+ For some types of Google Cloud resources, a binding
+ can also specify a condition, which is a logical
+ expression that allows access to a resource only if
+ the expression evaluates to true. A condition can add
+ constraints based on attributes of the request, the
+ resource, or both. To learn which resources support
+ conditions in their IAM policies, see the [IAM
+ documentation](https://cloud.google.com/iam/help/conditions/resource-policies).
+
+ **JSON example:**
+
+ :literal:`` { "bindings": [ { "role": "roles/resourcemanager.organizationAdmin", "members": [ "user:mike@example.com", "group:admins@example.com", "domain:google.com", "serviceAccount:my-project-id@appspot.gserviceaccount.com" ] }, { "role": "roles/resourcemanager.organizationViewer", "members": [ "user:eve@example.com" ], "condition": { "title": "expirable access", "description": "Does not grant access after Sep 2020", "expression": "request.time < timestamp('2020-10-01T00:00:00.000Z')", } } ], "etag": "BwWWja0YfJA=", "version": 3 }`\ \`
+
+ **YAML example:**
+
+ :literal:`` bindings: - members: - user:mike@example.com - group:admins@example.com - domain:google.com - serviceAccount:my-project-id@appspot.gserviceaccount.com role: roles/resourcemanager.organizationAdmin - members: - user:eve@example.com role: roles/resourcemanager.organizationViewer condition: title: expirable access description: Does not grant access after Sep 2020 expression: request.time < timestamp('2020-10-01T00:00:00.000Z') etag: BwWWja0YfJA= version: 3`\ \`
+
+ For a description of IAM and its features, see the
+ [IAM
+ documentation](https://cloud.google.com/iam/docs/).
+
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([backup, update_mask])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [resource]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_table_admin.UpdateBackupRequest(request)
-
- # If we have keyword arguments corresponding to fields on the
- # request, apply these.
- if backup is not None:
- request.backup = backup
- if update_mask is not None:
- request.update_mask = update_mask
+ # - The request isn't a proto-plus wrapped type,
+ # so it must be constructed via keyword expansion.
+ if isinstance(request, dict):
+ request = iam_policy_pb2.SetIamPolicyRequest(**request)
+ elif not request:
+ request = iam_policy_pb2.SetIamPolicyRequest(resource=resource)
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.update_backup,
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.set_iam_policy
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata(
- (("backup.name", request.backup.name),)
- ),
+ gapic_v1.routing_header.to_grpc_metadata((("resource", request.resource),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -1809,150 +4171,255 @@ async def update_backup(
# Done; return the response.
return response
- async def delete_backup(
+ async def test_iam_permissions(
self,
- request: Union[bigtable_table_admin.DeleteBackupRequest, dict] = None,
+ request: Optional[Union[iam_policy_pb2.TestIamPermissionsRequest, dict]] = None,
*,
- name: str = None,
+ resource: Optional[str] = None,
+ permissions: Optional[MutableSequence[str]] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
- ) -> None:
- r"""Deletes a pending or completed Cloud Bigtable backup.
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> iam_policy_pb2.TestIamPermissionsResponse:
+ r"""Returns permissions that the caller has on the
+ specified Bigtable resource.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+ from google.iam.v1 import iam_policy_pb2 # type: ignore
+
+ async def sample_test_iam_permissions():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = iam_policy_pb2.TestIamPermissionsRequest(
+ resource="resource_value",
+ permissions=['permissions_value1', 'permissions_value2'],
+ )
+
+ # Make the request
+ response = await client.test_iam_permissions(request=request)
+
+ # Handle the response
+ print(response)
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.DeleteBackupRequest, dict]):
- The request object. The request for
- [DeleteBackup][google.bigtable.admin.v2.BigtableTableAdmin.DeleteBackup].
- name (:class:`str`):
- Required. Name of the backup to delete. Values are of
- the form
- ``projects/{project}/instances/{instance}/clusters/{cluster}/backups/{backup}``.
+ request (Optional[Union[google.iam.v1.iam_policy_pb2.TestIamPermissionsRequest, dict]]):
+ The request object. Request message for ``TestIamPermissions`` method.
+ resource (:class:`str`):
+ REQUIRED: The resource for which the
+ policy detail is being requested. See
+ the operation documentation for the
+ appropriate value for this field.
- This corresponds to the ``name`` field
+ This corresponds to the ``resource`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ permissions (:class:`MutableSequence[str]`):
+ The set of permissions to check for the ``resource``.
+ Permissions with wildcards (such as '*' or 'storage.*')
+ are not allowed. For more information see `IAM
+ Overview `__.
+
+ This corresponds to the ``permissions`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.iam.v1.iam_policy_pb2.TestIamPermissionsResponse:
+ Response message for TestIamPermissions method.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [resource, permissions]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_table_admin.DeleteBackupRequest(request)
-
- # If we have keyword arguments corresponding to fields on the
- # request, apply these.
- if name is not None:
- request.name = name
+ # - The request isn't a proto-plus wrapped type,
+ # so it must be constructed via keyword expansion.
+ if isinstance(request, dict):
+ request = iam_policy_pb2.TestIamPermissionsRequest(**request)
+ elif not request:
+ request = iam_policy_pb2.TestIamPermissionsRequest(
+ resource=resource, permissions=permissions
+ )
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.delete_backup,
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.test_iam_permissions
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ gapic_v1.routing_header.to_grpc_metadata((("resource", request.resource),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
- await rpc(
+ response = await rpc(
request,
retry=retry,
timeout=timeout,
metadata=metadata,
)
- async def list_backups(
+ # Done; return the response.
+ return response
+
+ async def create_schema_bundle(
self,
- request: Union[bigtable_table_admin.ListBackupsRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_table_admin.CreateSchemaBundleRequest, dict]
+ ] = None,
*,
- parent: str = None,
+ parent: Optional[str] = None,
+ schema_bundle_id: Optional[str] = None,
+ schema_bundle: Optional[table.SchemaBundle] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
- ) -> pagers.ListBackupsAsyncPager:
- r"""Lists Cloud Bigtable backups. Returns both completed
- and pending backups.
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operation_async.AsyncOperation:
+ r"""Creates a new schema bundle in the specified table.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_create_schema_bundle():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ schema_bundle = bigtable_admin_v2.SchemaBundle()
+ schema_bundle.proto_schema.proto_descriptors = b'proto_descriptors_blob'
+
+ request = bigtable_admin_v2.CreateSchemaBundleRequest(
+ parent="parent_value",
+ schema_bundle_id="schema_bundle_id_value",
+ schema_bundle=schema_bundle,
+ )
+
+ # Make the request
+ operation = client.create_schema_bundle(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = (await operation).result()
+
+ # Handle the response
+ print(response)
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.ListBackupsRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.CreateSchemaBundleRequest, dict]]):
The request object. The request for
- [ListBackups][google.bigtable.admin.v2.BigtableTableAdmin.ListBackups].
+ [CreateSchemaBundle][google.bigtable.admin.v2.BigtableTableAdmin.CreateSchemaBundle].
parent (:class:`str`):
- Required. The cluster to list backups from. Values are
- of the form
- ``projects/{project}/instances/{instance}/clusters/{cluster}``.
- Use ``{cluster} = '-'`` to list backups for all clusters
- in an instance, e.g.,
- ``projects/{project}/instances/{instance}/clusters/-``.
+ Required. The parent resource where this schema bundle
+ will be created. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}``.
This corresponds to the ``parent`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ schema_bundle_id (:class:`str`):
+ Required. The unique ID to use for
+ the schema bundle, which will become the
+ final component of the schema bundle's
+ resource name.
+
+ This corresponds to the ``schema_bundle_id`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ schema_bundle (:class:`google.cloud.bigtable_admin_v2.types.SchemaBundle`):
+ Required. The schema bundle to
+ create.
+
+ This corresponds to the ``schema_bundle`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
- google.cloud.bigtable_admin_v2.services.bigtable_table_admin.pagers.ListBackupsAsyncPager:
- The response for
- [ListBackups][google.bigtable.admin.v2.BigtableTableAdmin.ListBackups].
+ google.api_core.operation_async.AsyncOperation:
+ An object representing a long-running operation.
- Iterating over this object will yield results and
- resolve additional pages automatically.
+ The result type for the operation will be
+ :class:`google.cloud.bigtable_admin_v2.types.SchemaBundle`
+ A named collection of related schemas.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([parent])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent, schema_bundle_id, schema_bundle]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable_table_admin.ListBackupsRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.CreateSchemaBundleRequest):
+ request = bigtable_table_admin.CreateSchemaBundleRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
if parent is not None:
request.parent = parent
+ if schema_bundle_id is not None:
+ request.schema_bundle_id = schema_bundle_id
+ if schema_bundle is not None:
+ request.schema_bundle = schema_bundle
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.list_backups,
- default_retry=retries.Retry(
- initial=1.0,
- maximum=60.0,
- multiplier=2,
- predicate=retries.if_exception_type(
- core_exceptions.DeadlineExceeded,
- core_exceptions.ServiceUnavailable,
- ),
- deadline=60.0,
- ),
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.create_schema_bundle
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -1960,6 +4427,9 @@ async def list_backups(
gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -1968,72 +4438,144 @@ async def list_backups(
metadata=metadata,
)
- # This method is paged; wrap the response in a pager, which provides
- # an `__aiter__` convenience method.
- response = pagers.ListBackupsAsyncPager(
- method=rpc,
- request=request,
- response=response,
- metadata=metadata,
+ # Wrap the response in an operation future.
+ response = operation_async.from_gapic(
+ response,
+ self._client._transport.operations_client,
+ table.SchemaBundle,
+ metadata_type=bigtable_table_admin.CreateSchemaBundleMetadata,
)
# Done; return the response.
return response
- async def restore_table(
+ async def update_schema_bundle(
self,
- request: Union[bigtable_table_admin.RestoreTableRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_table_admin.UpdateSchemaBundleRequest, dict]
+ ] = None,
*,
+ schema_bundle: Optional[table.SchemaBundle] = None,
+ update_mask: Optional[field_mask_pb2.FieldMask] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> operation_async.AsyncOperation:
- r"""Create a new table by restoring from a completed backup. The new
- table must be in the same project as the instance containing the
- backup. The returned table [long-running
- operation][google.longrunning.Operation] can be used to track
- the progress of the operation, and to cancel it. The
- [metadata][google.longrunning.Operation.metadata] field type is
- [RestoreTableMetadata][google.bigtable.admin.RestoreTableMetadata].
- The [response][google.longrunning.Operation.response] type is
- [Table][google.bigtable.admin.v2.Table], if successful.
+ r"""Updates a schema bundle in the specified table.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_update_schema_bundle():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ schema_bundle = bigtable_admin_v2.SchemaBundle()
+ schema_bundle.proto_schema.proto_descriptors = b'proto_descriptors_blob'
+
+ request = bigtable_admin_v2.UpdateSchemaBundleRequest(
+ schema_bundle=schema_bundle,
+ )
+
+ # Make the request
+ operation = client.update_schema_bundle(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = (await operation).result()
+
+ # Handle the response
+ print(response)
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.RestoreTableRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.UpdateSchemaBundleRequest, dict]]):
The request object. The request for
- [RestoreTable][google.bigtable.admin.v2.BigtableTableAdmin.RestoreTable].
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ [UpdateSchemaBundle][google.bigtable.admin.v2.BigtableTableAdmin.UpdateSchemaBundle].
+ schema_bundle (:class:`google.cloud.bigtable_admin_v2.types.SchemaBundle`):
+ Required. The schema bundle to update.
+
+ The schema bundle's ``name`` field is used to identify
+ the schema bundle to update. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}/schemaBundles/{schema_bundle}``
+
+ This corresponds to the ``schema_bundle`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`):
+ Optional. The list of fields to
+ update.
+
+ This corresponds to the ``update_mask`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.api_core.operation_async.AsyncOperation:
An object representing a long-running operation.
- The result type for the operation will be :class:`google.cloud.bigtable_admin_v2.types.Table` A collection of user data indexed by row, column, and timestamp.
- Each table is served using the resources of its
- parent cluster.
+ The result type for the operation will be
+ :class:`google.cloud.bigtable_admin_v2.types.SchemaBundle`
+ A named collection of related schemas.
"""
# Create or coerce a protobuf request object.
- request = bigtable_table_admin.RestoreTableRequest(request)
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [schema_bundle, update_mask]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.UpdateSchemaBundleRequest):
+ request = bigtable_table_admin.UpdateSchemaBundleRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if schema_bundle is not None:
+ request.schema_bundle = schema_bundle
+ if update_mask is not None:
+ request.update_mask = update_mask
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.restore_table,
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.update_schema_bundle
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ gapic_v1.routing_header.to_grpc_metadata(
+ (("schema_bundle.name", request.schema_bundle.name),)
+ ),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -2046,153 +4588,117 @@ async def restore_table(
response = operation_async.from_gapic(
response,
self._client._transport.operations_client,
- table.Table,
- metadata_type=bigtable_table_admin.RestoreTableMetadata,
+ table.SchemaBundle,
+ metadata_type=bigtable_table_admin.UpdateSchemaBundleMetadata,
)
# Done; return the response.
return response
- async def get_iam_policy(
+ async def get_schema_bundle(
self,
- request: Union[iam_policy_pb2.GetIamPolicyRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_table_admin.GetSchemaBundleRequest, dict]
+ ] = None,
*,
- resource: str = None,
+ name: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
- ) -> policy_pb2.Policy:
- r"""Gets the access control policy for a Table or Backup
- resource. Returns an empty policy if the resource exists
- but does not have a policy set.
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> table.SchemaBundle:
+ r"""Gets metadata information about the specified schema
+ bundle.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_get_schema_bundle():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.GetSchemaBundleRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ response = await client.get_schema_bundle(request=request)
+
+ # Handle the response
+ print(response)
Args:
- request (Union[google.iam.v1.iam_policy_pb2.GetIamPolicyRequest, dict]):
- The request object. Request message for `GetIamPolicy`
- method.
- resource (:class:`str`):
- REQUIRED: The resource for which the
- policy is being requested. See the
- operation documentation for the
- appropriate value for this field.
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.GetSchemaBundleRequest, dict]]):
+ The request object. The request for
+ [GetSchemaBundle][google.bigtable.admin.v2.BigtableTableAdmin.GetSchemaBundle].
+ name (:class:`str`):
+ Required. The unique name of the schema bundle to
+ retrieve. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}/schemaBundles/{schema_bundle}``
- This corresponds to the ``resource`` field
+ This corresponds to the ``name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
- google.iam.v1.policy_pb2.Policy:
- An Identity and Access Management (IAM) policy, which specifies access
- controls for Google Cloud resources.
-
- A Policy is a collection of bindings. A binding binds
- one or more members, or principals, to a single role.
- Principals can be user accounts, service accounts,
- Google groups, and domains (such as G Suite). A role
- is a named list of permissions; each role can be an
- IAM predefined role or a user-created custom role.
-
- For some types of Google Cloud resources, a binding
- can also specify a condition, which is a logical
- expression that allows access to a resource only if
- the expression evaluates to true. A condition can add
- constraints based on attributes of the request, the
- resource, or both. To learn which resources support
- conditions in their IAM policies, see the [IAM
- documentation](\ https://cloud.google.com/iam/help/conditions/resource-policies).
-
- **JSON example:**
-
- {
- "bindings": [
- {
- "role":
- "roles/resourcemanager.organizationAdmin",
- "members": [ "user:mike@example.com",
- "group:admins@example.com",
- "domain:google.com",
- "serviceAccount:my-project-id@appspot.gserviceaccount.com"
- ]
-
- }, { "role":
- "roles/resourcemanager.organizationViewer",
- "members": [ "user:eve@example.com" ],
- "condition": { "title": "expirable access",
- "description": "Does not grant access after
- Sep 2020", "expression": "request.time <
- timestamp('2020-10-01T00:00:00.000Z')", } }
-
- ], "etag": "BwWWja0YfJA=", "version": 3
-
- }
-
- **YAML example:**
-
- bindings: - members: - user:\ mike@example.com -
- group:\ admins@example.com - domain:google.com -
- serviceAccount:\ my-project-id@appspot.gserviceaccount.com
- role: roles/resourcemanager.organizationAdmin -
- members: - user:\ eve@example.com role:
- roles/resourcemanager.organizationViewer
- condition: title: expirable access description:
- Does not grant access after Sep 2020 expression:
- request.time <
- timestamp('2020-10-01T00:00:00.000Z') etag:
- BwWWja0YfJA= version: 3
-
- For a description of IAM and its features, see the
- [IAM
- documentation](\ https://cloud.google.com/iam/docs/).
+ google.cloud.bigtable_admin_v2.types.SchemaBundle:
+ A named collection of related
+ schemas.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([resource])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # The request isn't a proto-plus wrapped type,
- # so it must be constructed via keyword expansion.
- if isinstance(request, dict):
- request = iam_policy_pb2.GetIamPolicyRequest(**request)
- elif not request:
- request = iam_policy_pb2.GetIamPolicyRequest(
- resource=resource,
- )
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.GetSchemaBundleRequest):
+ request = bigtable_table_admin.GetSchemaBundleRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if name is not None:
+ request.name = name
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.get_iam_policy,
- default_retry=retries.Retry(
- initial=1.0,
- maximum=60.0,
- multiplier=2,
- predicate=retries.if_exception_type(
- core_exceptions.DeadlineExceeded,
- core_exceptions.ServiceUnavailable,
- ),
- deadline=60.0,
- ),
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.get_schema_bundle
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata((("resource", request.resource),)),
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -2204,135 +4710,114 @@ async def get_iam_policy(
# Done; return the response.
return response
- async def set_iam_policy(
+ async def list_schema_bundles(
self,
- request: Union[iam_policy_pb2.SetIamPolicyRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_table_admin.ListSchemaBundlesRequest, dict]
+ ] = None,
*,
- resource: str = None,
+ parent: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
- ) -> policy_pb2.Policy:
- r"""Sets the access control policy on a Table or Backup
- resource. Replaces any existing policy.
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> pagers.ListSchemaBundlesAsyncPager:
+ r"""Lists all schema bundles associated with the
+ specified table.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ async def sample_list_schema_bundles():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.ListSchemaBundlesRequest(
+ parent="parent_value",
+ )
+
+ # Make the request
+ page_result = client.list_schema_bundles(request=request)
+
+ # Handle the response
+ async for response in page_result:
+ print(response)
Args:
- request (Union[google.iam.v1.iam_policy_pb2.SetIamPolicyRequest, dict]):
- The request object. Request message for `SetIamPolicy`
- method.
- resource (:class:`str`):
- REQUIRED: The resource for which the
- policy is being specified. See the
- operation documentation for the
- appropriate value for this field.
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.ListSchemaBundlesRequest, dict]]):
+ The request object. The request for
+ [ListSchemaBundles][google.bigtable.admin.v2.BigtableTableAdmin.ListSchemaBundles].
+ parent (:class:`str`):
+ Required. The parent, which owns this collection of
+ schema bundles. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}``.
- This corresponds to the ``resource`` field
+ This corresponds to the ``parent`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
- google.iam.v1.policy_pb2.Policy:
- An Identity and Access Management (IAM) policy, which specifies access
- controls for Google Cloud resources.
-
- A Policy is a collection of bindings. A binding binds
- one or more members, or principals, to a single role.
- Principals can be user accounts, service accounts,
- Google groups, and domains (such as G Suite). A role
- is a named list of permissions; each role can be an
- IAM predefined role or a user-created custom role.
-
- For some types of Google Cloud resources, a binding
- can also specify a condition, which is a logical
- expression that allows access to a resource only if
- the expression evaluates to true. A condition can add
- constraints based on attributes of the request, the
- resource, or both. To learn which resources support
- conditions in their IAM policies, see the [IAM
- documentation](\ https://cloud.google.com/iam/help/conditions/resource-policies).
-
- **JSON example:**
-
- {
- "bindings": [
- {
- "role":
- "roles/resourcemanager.organizationAdmin",
- "members": [ "user:mike@example.com",
- "group:admins@example.com",
- "domain:google.com",
- "serviceAccount:my-project-id@appspot.gserviceaccount.com"
- ]
-
- }, { "role":
- "roles/resourcemanager.organizationViewer",
- "members": [ "user:eve@example.com" ],
- "condition": { "title": "expirable access",
- "description": "Does not grant access after
- Sep 2020", "expression": "request.time <
- timestamp('2020-10-01T00:00:00.000Z')", } }
-
- ], "etag": "BwWWja0YfJA=", "version": 3
-
- }
-
- **YAML example:**
-
- bindings: - members: - user:\ mike@example.com -
- group:\ admins@example.com - domain:google.com -
- serviceAccount:\ my-project-id@appspot.gserviceaccount.com
- role: roles/resourcemanager.organizationAdmin -
- members: - user:\ eve@example.com role:
- roles/resourcemanager.organizationViewer
- condition: title: expirable access description:
- Does not grant access after Sep 2020 expression:
- request.time <
- timestamp('2020-10-01T00:00:00.000Z') etag:
- BwWWja0YfJA= version: 3
+ google.cloud.bigtable_admin_v2.services.bigtable_table_admin.pagers.ListSchemaBundlesAsyncPager:
+ The response for
+ [ListSchemaBundles][google.bigtable.admin.v2.BigtableTableAdmin.ListSchemaBundles].
- For a description of IAM and its features, see the
- [IAM
- documentation](\ https://cloud.google.com/iam/docs/).
+ Iterating over this object will yield results and
+ resolve additional pages automatically.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([resource])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # The request isn't a proto-plus wrapped type,
- # so it must be constructed via keyword expansion.
- if isinstance(request, dict):
- request = iam_policy_pb2.SetIamPolicyRequest(**request)
- elif not request:
- request = iam_policy_pb2.SetIamPolicyRequest(
- resource=resource,
- )
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.ListSchemaBundlesRequest):
+ request = bigtable_table_admin.ListSchemaBundlesRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if parent is not None:
+ request.parent = parent
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.set_iam_policy,
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.list_schema_bundles
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata((("resource", request.resource),)),
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -2341,124 +4826,135 @@ async def set_iam_policy(
metadata=metadata,
)
+ # This method is paged; wrap the response in a pager, which provides
+ # an `__aiter__` convenience method.
+ response = pagers.ListSchemaBundlesAsyncPager(
+ method=rpc,
+ request=request,
+ response=response,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
# Done; return the response.
return response
- async def test_iam_permissions(
+ async def delete_schema_bundle(
self,
- request: Union[iam_policy_pb2.TestIamPermissionsRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_table_admin.DeleteSchemaBundleRequest, dict]
+ ] = None,
*,
- resource: str = None,
- permissions: Sequence[str] = None,
+ name: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
- ) -> iam_policy_pb2.TestIamPermissionsResponse:
- r"""Returns permissions that the caller has on the
- specified Table or Backup resource.
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> None:
+ r"""Deletes a schema bundle in the specified table.
- Args:
- request (Union[google.iam.v1.iam_policy_pb2.TestIamPermissionsRequest, dict]):
- The request object. Request message for
- `TestIamPermissions` method.
- resource (:class:`str`):
- REQUIRED: The resource for which the
- policy detail is being requested. See
- the operation documentation for the
- appropriate value for this field.
+ .. code-block:: python
- This corresponds to the ``resource`` field
- on the ``request`` instance; if ``request`` is provided, this
- should not be set.
- permissions (:class:`Sequence[str]`):
- The set of permissions to check for the ``resource``.
- Permissions with wildcards (such as '*' or 'storage.*')
- are not allowed. For more information see `IAM
- Overview `__.
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
- This corresponds to the ``permissions`` field
+ async def sample_delete_schema_bundle():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminAsyncClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.DeleteSchemaBundleRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ await client.delete_schema_bundle(request=request)
+
+ Args:
+ request (Optional[Union[google.cloud.bigtable_admin_v2.types.DeleteSchemaBundleRequest, dict]]):
+ The request object. The request for
+ [DeleteSchemaBundle][google.bigtable.admin.v2.BigtableTableAdmin.DeleteSchemaBundle].
+ name (:class:`str`):
+ Required. The unique name of the schema bundle to
+ delete. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}/schemaBundles/{schema_bundle}``
+
+ This corresponds to the ``name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
-
- Returns:
- google.iam.v1.iam_policy_pb2.TestIamPermissionsResponse:
- Response message for TestIamPermissions method.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([resource, permissions])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # The request isn't a proto-plus wrapped type,
- # so it must be constructed via keyword expansion.
- if isinstance(request, dict):
- request = iam_policy_pb2.TestIamPermissionsRequest(**request)
- elif not request:
- request = iam_policy_pb2.TestIamPermissionsRequest(
- resource=resource,
- permissions=permissions,
- )
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.DeleteSchemaBundleRequest):
+ request = bigtable_table_admin.DeleteSchemaBundleRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if name is not None:
+ request.name = name
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.test_iam_permissions,
- default_retry=retries.Retry(
- initial=1.0,
- maximum=60.0,
- multiplier=2,
- predicate=retries.if_exception_type(
- core_exceptions.DeadlineExceeded,
- core_exceptions.ServiceUnavailable,
- ),
- deadline=60.0,
- ),
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.delete_schema_bundle
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata((("resource", request.resource),)),
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
- response = await rpc(
+ await rpc(
request,
retry=retry,
timeout=timeout,
metadata=metadata,
)
- # Done; return the response.
- return response
-
- async def __aenter__(self):
+ async def __aenter__(self) -> "BaseBigtableTableAdminAsyncClient":
return self
async def __aexit__(self, exc_type, exc, tb):
await self.transport.close()
-try:
- DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
- gapic_version=pkg_resources.get_distribution(
- "google-cloud-bigtable-admin",
- ).version,
- )
-except pkg_resources.DistributionNotFound:
- DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
+DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
+ gapic_version=package_version.__version__
+)
+
+if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER
+ DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__
-__all__ = ("BigtableTableAdminAsyncClient",)
+__all__ = ("BaseBigtableTableAdminAsyncClient",)
diff --git a/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/client.py b/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/client.py
index 3b1185e53..ce251db7d 100644
--- a/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/client.py
+++ b/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/client.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -14,10 +14,27 @@
# limitations under the License.
#
from collections import OrderedDict
+from http import HTTPStatus
+import json
+import logging as std_logging
import os
import re
-from typing import Dict, Mapping, Optional, Sequence, Tuple, Type, Union
-import pkg_resources
+from typing import (
+ Dict,
+ Callable,
+ Mapping,
+ MutableMapping,
+ MutableSequence,
+ Optional,
+ Sequence,
+ Tuple,
+ Type,
+ Union,
+ cast,
+)
+import warnings
+
+from google.cloud.bigtable_admin_v2 import gapic_version as package_version
from google.api_core import client_options as client_options_lib
from google.api_core import exceptions as core_exceptions
@@ -28,11 +45,21 @@
from google.auth.transport.grpc import SslCredentials # type: ignore
from google.auth.exceptions import MutualTLSChannelError # type: ignore
from google.oauth2 import service_account # type: ignore
+import google.protobuf
try:
- OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault]
+ OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None]
except AttributeError: # pragma: NO COVER
- OptionalRetry = Union[retries.Retry, object] # type: ignore
+ OptionalRetry = Union[retries.Retry, object, None] # type: ignore
+
+try:
+ from google.api_core import client_logging # type: ignore
+
+ CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER
+except ImportError: # pragma: NO COVER
+ CLIENT_LOGGING_SUPPORTED = False
+
+_LOGGER = std_logging.getLogger(__name__)
from google.api_core import operation # type: ignore
from google.api_core import operation_async # type: ignore
@@ -40,6 +67,7 @@
from google.cloud.bigtable_admin_v2.types import bigtable_table_admin
from google.cloud.bigtable_admin_v2.types import table
from google.cloud.bigtable_admin_v2.types import table as gba_table
+from google.cloud.bigtable_admin_v2.types import types
from google.iam.v1 import iam_policy_pb2 # type: ignore
from google.iam.v1 import policy_pb2 # type: ignore
from google.protobuf import field_mask_pb2 # type: ignore
@@ -47,9 +75,10 @@
from .transports.base import BigtableTableAdminTransport, DEFAULT_CLIENT_INFO
from .transports.grpc import BigtableTableAdminGrpcTransport
from .transports.grpc_asyncio import BigtableTableAdminGrpcAsyncIOTransport
+from .transports.rest import BigtableTableAdminRestTransport
-class BigtableTableAdminClientMeta(type):
+class BaseBigtableTableAdminClientMeta(type):
"""Metaclass for the BigtableTableAdmin client.
This provides class-level methods for building and retrieving
@@ -62,10 +91,11 @@ class BigtableTableAdminClientMeta(type):
) # type: Dict[str, Type[BigtableTableAdminTransport]]
_transport_registry["grpc"] = BigtableTableAdminGrpcTransport
_transport_registry["grpc_asyncio"] = BigtableTableAdminGrpcAsyncIOTransport
+ _transport_registry["rest"] = BigtableTableAdminRestTransport
def get_transport_class(
cls,
- label: str = None,
+ label: Optional[str] = None,
) -> Type[BigtableTableAdminTransport]:
"""Returns an appropriate transport class.
@@ -85,7 +115,7 @@ def get_transport_class(
return next(iter(cls._transport_registry.values()))
-class BigtableTableAdminClient(metaclass=BigtableTableAdminClientMeta):
+class BaseBigtableTableAdminClient(metaclass=BaseBigtableTableAdminClientMeta):
"""Service for creating, configuring, and deleting Cloud
Bigtable tables.
@@ -123,11 +153,43 @@ def _get_default_mtls_endpoint(api_endpoint):
return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com")
+ # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead.
DEFAULT_ENDPOINT = "bigtableadmin.googleapis.com"
DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore
DEFAULT_ENDPOINT
)
+ _DEFAULT_ENDPOINT_TEMPLATE = "bigtableadmin.{UNIVERSE_DOMAIN}"
+ _DEFAULT_UNIVERSE = "googleapis.com"
+
+ @staticmethod
+ def _use_client_cert_effective():
+ """Returns whether client certificate should be used for mTLS if the
+ google-auth version supports should_use_client_cert automatic mTLS enablement.
+
+ Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var.
+
+ Returns:
+ bool: whether client certificate should be used for mTLS
+ Raises:
+ ValueError: (If using a version of google-auth without should_use_client_cert and
+ GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.)
+ """
+ # check if google-auth version supports should_use_client_cert for automatic mTLS enablement
+ if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER
+ return mtls.should_use_client_cert()
+ else: # pragma: NO COVER
+ # if unsupported, fallback to reading from env var
+ use_client_cert_str = os.getenv(
+ "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"
+ ).lower()
+ if use_client_cert_str not in ("true", "false"):
+ raise ValueError(
+ "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be"
+ " either `true` or `false`"
+ )
+ return use_client_cert_str == "true"
+
@classmethod
def from_service_account_info(cls, info: dict, *args, **kwargs):
"""Creates an instance of this client using the provided credentials
@@ -139,7 +201,7 @@ def from_service_account_info(cls, info: dict, *args, **kwargs):
kwargs: Additional arguments to pass to the constructor.
Returns:
- BigtableTableAdminClient: The constructed client.
+ BaseBigtableTableAdminClient: The constructed client.
"""
credentials = service_account.Credentials.from_service_account_info(info)
kwargs["credentials"] = credentials
@@ -157,7 +219,7 @@ def from_service_account_file(cls, filename: str, *args, **kwargs):
kwargs: Additional arguments to pass to the constructor.
Returns:
- BigtableTableAdminClient: The constructed client.
+ BaseBigtableTableAdminClient: The constructed client.
"""
credentials = service_account.Credentials.from_service_account_file(filename)
kwargs["credentials"] = credentials
@@ -175,6 +237,30 @@ def transport(self) -> BigtableTableAdminTransport:
"""
return self._transport
+ @staticmethod
+ def authorized_view_path(
+ project: str,
+ instance: str,
+ table: str,
+ authorized_view: str,
+ ) -> str:
+ """Returns a fully-qualified authorized_view string."""
+ return "projects/{project}/instances/{instance}/tables/{table}/authorizedViews/{authorized_view}".format(
+ project=project,
+ instance=instance,
+ table=table,
+ authorized_view=authorized_view,
+ )
+
+ @staticmethod
+ def parse_authorized_view_path(path: str) -> Dict[str, str]:
+ """Parses a authorized_view path into its component segments."""
+ m = re.match(
+ r"^projects/(?P.+?)/instances/(?P.+?)/tables/(?P.+?)/authorizedViews/(?P.+?)$",
+ path,
+ )
+ return m.groupdict() if m else {}
+
@staticmethod
def backup_path(
project: str,
@@ -264,6 +350,30 @@ def parse_instance_path(path: str) -> Dict[str, str]:
m = re.match(r"^projects/(?P.+?)/instances/(?P.+?)$", path)
return m.groupdict() if m else {}
+ @staticmethod
+ def schema_bundle_path(
+ project: str,
+ instance: str,
+ table: str,
+ schema_bundle: str,
+ ) -> str:
+ """Returns a fully-qualified schema_bundle string."""
+ return "projects/{project}/instances/{instance}/tables/{table}/schemaBundles/{schema_bundle}".format(
+ project=project,
+ instance=instance,
+ table=table,
+ schema_bundle=schema_bundle,
+ )
+
+ @staticmethod
+ def parse_schema_bundle_path(path: str) -> Dict[str, str]:
+ """Parses a schema_bundle path into its component segments."""
+ m = re.match(
+ r"^projects/(?P.+?)/instances/(?P.+?)/tables/(?P.+?)/schemaBundles/(?P.+?)$",
+ path,
+ )
+ return m.groupdict() if m else {}
+
@staticmethod
def snapshot_path(
project: str,
@@ -391,7 +501,7 @@ def parse_common_location_path(path: str) -> Dict[str, str]:
def get_mtls_endpoint_and_cert_source(
cls, client_options: Optional[client_options_lib.ClientOptions] = None
):
- """Return the API endpoint and client cert source for mutual TLS.
+ """Deprecated. Return the API endpoint and client cert source for mutual TLS.
The client cert source is determined in the following order:
(1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the
@@ -403,7 +513,7 @@ def get_mtls_endpoint_and_cert_source(
The API endpoint is determined in the following order:
(1) if `client_options.api_endpoint` if provided, use the provided one.
(2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the
- default mTLS endpoint; if the environment variabel is "never", use the default API
+ default mTLS endpoint; if the environment variable is "never", use the default API
endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise
use the default API endpoint.
@@ -421,14 +531,15 @@ def get_mtls_endpoint_and_cert_source(
Raises:
google.auth.exceptions.MutualTLSChannelError: If any errors happen.
"""
+
+ warnings.warn(
+ "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.",
+ DeprecationWarning,
+ )
if client_options is None:
client_options = client_options_lib.ClientOptions()
- use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")
+ use_client_cert = BaseBigtableTableAdminClient._use_client_cert_effective()
use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto")
- if use_client_cert not in ("true", "false"):
- raise ValueError(
- "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
- )
if use_mtls_endpoint not in ("auto", "never", "always"):
raise MutualTLSChannelError(
"Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
@@ -436,7 +547,7 @@ def get_mtls_endpoint_and_cert_source(
# Figure out the client cert source to use.
client_cert_source = None
- if use_client_cert == "true":
+ if use_client_cert:
if client_options.client_cert_source:
client_cert_source = client_options.client_cert_source
elif mtls.has_default_client_cert_source():
@@ -454,15 +565,182 @@ def get_mtls_endpoint_and_cert_source(
return api_endpoint, client_cert_source
+ @staticmethod
+ def _read_environment_variables():
+ """Returns the environment variables used by the client.
+
+ Returns:
+ Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE,
+ GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables.
+
+ Raises:
+ ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not
+ any of ["true", "false"].
+ google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT
+ is not any of ["auto", "never", "always"].
+ """
+ use_client_cert = BaseBigtableTableAdminClient._use_client_cert_effective()
+ use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower()
+ universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN")
+ if use_mtls_endpoint not in ("auto", "never", "always"):
+ raise MutualTLSChannelError(
+ "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
+ )
+ return use_client_cert, use_mtls_endpoint, universe_domain_env
+
+ @staticmethod
+ def _get_client_cert_source(provided_cert_source, use_cert_flag):
+ """Return the client cert source to be used by the client.
+
+ Args:
+ provided_cert_source (bytes): The client certificate source provided.
+ use_cert_flag (bool): A flag indicating whether to use the client certificate.
+
+ Returns:
+ bytes or None: The client cert source to be used by the client.
+ """
+ client_cert_source = None
+ if use_cert_flag:
+ if provided_cert_source:
+ client_cert_source = provided_cert_source
+ elif mtls.has_default_client_cert_source():
+ client_cert_source = mtls.default_client_cert_source()
+ return client_cert_source
+
+ @staticmethod
+ def _get_api_endpoint(
+ api_override, client_cert_source, universe_domain, use_mtls_endpoint
+ ):
+ """Return the API endpoint used by the client.
+
+ Args:
+ api_override (str): The API endpoint override. If specified, this is always
+ the return value of this function and the other arguments are not used.
+ client_cert_source (bytes): The client certificate source used by the client.
+ universe_domain (str): The universe domain used by the client.
+ use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters.
+ Possible values are "always", "auto", or "never".
+
+ Returns:
+ str: The API endpoint to be used by the client.
+ """
+ if api_override is not None:
+ api_endpoint = api_override
+ elif use_mtls_endpoint == "always" or (
+ use_mtls_endpoint == "auto" and client_cert_source
+ ):
+ _default_universe = BaseBigtableTableAdminClient._DEFAULT_UNIVERSE
+ if universe_domain != _default_universe:
+ raise MutualTLSChannelError(
+ f"mTLS is not supported in any universe other than {_default_universe}."
+ )
+ api_endpoint = BaseBigtableTableAdminClient.DEFAULT_MTLS_ENDPOINT
+ else:
+ api_endpoint = (
+ BaseBigtableTableAdminClient._DEFAULT_ENDPOINT_TEMPLATE.format(
+ UNIVERSE_DOMAIN=universe_domain
+ )
+ )
+ return api_endpoint
+
+ @staticmethod
+ def _get_universe_domain(
+ client_universe_domain: Optional[str], universe_domain_env: Optional[str]
+ ) -> str:
+ """Return the universe domain used by the client.
+
+ Args:
+ client_universe_domain (Optional[str]): The universe domain configured via the client options.
+ universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable.
+
+ Returns:
+ str: The universe domain to be used by the client.
+
+ Raises:
+ ValueError: If the universe domain is an empty string.
+ """
+ universe_domain = BaseBigtableTableAdminClient._DEFAULT_UNIVERSE
+ if client_universe_domain is not None:
+ universe_domain = client_universe_domain
+ elif universe_domain_env is not None:
+ universe_domain = universe_domain_env
+ if len(universe_domain.strip()) == 0:
+ raise ValueError("Universe Domain cannot be an empty string.")
+ return universe_domain
+
+ def _validate_universe_domain(self):
+ """Validates client's and credentials' universe domains are consistent.
+
+ Returns:
+ bool: True iff the configured universe domain is valid.
+
+ Raises:
+ ValueError: If the configured universe domain is not valid.
+ """
+
+ # NOTE (b/349488459): universe validation is disabled until further notice.
+ return True
+
+ def _add_cred_info_for_auth_errors(
+ self, error: core_exceptions.GoogleAPICallError
+ ) -> None:
+ """Adds credential info string to error details for 401/403/404 errors.
+
+ Args:
+ error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info.
+ """
+ if error.code not in [
+ HTTPStatus.UNAUTHORIZED,
+ HTTPStatus.FORBIDDEN,
+ HTTPStatus.NOT_FOUND,
+ ]:
+ return
+
+ cred = self._transport._credentials
+
+ # get_cred_info is only available in google-auth>=2.35.0
+ if not hasattr(cred, "get_cred_info"):
+ return
+
+ # ignore the type check since pypy test fails when get_cred_info
+ # is not available
+ cred_info = cred.get_cred_info() # type: ignore
+ if cred_info and hasattr(error._details, "append"):
+ error._details.append(json.dumps(cred_info))
+
+ @property
+ def api_endpoint(self):
+ """Return the API endpoint used by the client instance.
+
+ Returns:
+ str: The API endpoint used by the client instance.
+ """
+ return self._api_endpoint
+
+ @property
+ def universe_domain(self) -> str:
+ """Return the universe domain used by the client instance.
+
+ Returns:
+ str: The universe domain used by the client instance.
+ """
+ return self._universe_domain
+
def __init__(
self,
*,
credentials: Optional[ga_credentials.Credentials] = None,
- transport: Union[str, BigtableTableAdminTransport, None] = None,
- client_options: Optional[client_options_lib.ClientOptions] = None,
+ transport: Optional[
+ Union[
+ str,
+ BigtableTableAdminTransport,
+ Callable[..., BigtableTableAdminTransport],
+ ]
+ ] = None,
+ client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None,
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
- """Instantiates the bigtable table admin client.
+ """Instantiates the base bigtable table admin client.
Args:
credentials (Optional[google.auth.credentials.Credentials]): The
@@ -470,25 +748,37 @@ def __init__(
credentials identify the application to the service; if none
are specified, the client will attempt to ascertain the
credentials from the environment.
- transport (Union[str, BigtableTableAdminTransport]): The
- transport to use. If set to None, a transport is chosen
- automatically.
- client_options (google.api_core.client_options.ClientOptions): Custom options for the
- client. It won't take effect if a ``transport`` instance is provided.
- (1) The ``api_endpoint`` property can be used to override the
- default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
- environment variable can also be used to override the endpoint:
+ transport (Optional[Union[str,BigtableTableAdminTransport,Callable[..., BigtableTableAdminTransport]]]):
+ The transport to use, or a Callable that constructs and returns a new transport.
+ If a Callable is given, it will be called with the same set of initialization
+ arguments as used in the BigtableTableAdminTransport constructor.
+ If set to None, a transport is chosen automatically.
+ client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]):
+ Custom options for the client.
+
+ 1. The ``api_endpoint`` property can be used to override the
+ default endpoint provided by the client when ``transport`` is
+ not explicitly provided. Only if this property is not set and
+ ``transport`` was not explicitly provided, the endpoint is
+ determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment
+ variable, which have one of the following values:
"always" (always use the default mTLS endpoint), "never" (always
- use the default regular endpoint) and "auto" (auto switch to the
- default mTLS endpoint if client certificate is present, this is
- the default value). However, the ``api_endpoint`` property takes
- precedence if provided.
- (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ use the default regular endpoint) and "auto" (auto-switch to the
+ default mTLS endpoint if client certificate is present; this is
+ the default value).
+
+ 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
is "true", then the ``client_cert_source`` property can be used
- to provide client certificate for mutual TLS transport. If
+ to provide a client certificate for mTLS transport. If
not provided, the default SSL client certificate will be used if
present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
set, no client certificate will be used.
+
+ 3. The ``universe_domain`` property can be used to override the
+ default "googleapis.com" universe. Note that the ``api_endpoint``
+ property still takes precedence; and ``universe_domain`` is
+ currently not supported for mTLS.
+
client_info (google.api_core.gapic_v1.client_info.ClientInfo):
The client info used to send a user-agent string along with
API requests. If ``None``, then default info will be used.
@@ -499,16 +789,38 @@ def __init__(
google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
creation failed for any reason.
"""
- if isinstance(client_options, dict):
- client_options = client_options_lib.from_dict(client_options)
- if client_options is None:
- client_options = client_options_lib.ClientOptions()
+ self._client_options = client_options
+ if isinstance(self._client_options, dict):
+ self._client_options = client_options_lib.from_dict(self._client_options)
+ if self._client_options is None:
+ self._client_options = client_options_lib.ClientOptions()
+ self._client_options = cast(
+ client_options_lib.ClientOptions, self._client_options
+ )
- api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source(
- client_options
+ universe_domain_opt = getattr(self._client_options, "universe_domain", None)
+
+ (
+ self._use_client_cert,
+ self._use_mtls_endpoint,
+ self._universe_domain_env,
+ ) = BaseBigtableTableAdminClient._read_environment_variables()
+ self._client_cert_source = BaseBigtableTableAdminClient._get_client_cert_source(
+ self._client_options.client_cert_source, self._use_client_cert
+ )
+ self._universe_domain = BaseBigtableTableAdminClient._get_universe_domain(
+ universe_domain_opt, self._universe_domain_env
)
+ self._api_endpoint = None # updated below, depending on `transport`
+
+ # Initialize the universe domain validation.
+ self._is_universe_domain_valid = False
+
+ if CLIENT_LOGGING_SUPPORTED: # pragma: NO COVER
+ # Setup logging.
+ client_logging.initialize_logging()
- api_key_value = getattr(client_options, "api_key", None)
+ api_key_value = getattr(self._client_options, "api_key", None)
if api_key_value and credentials:
raise ValueError(
"client_options.api_key and credentials are mutually exclusive"
@@ -517,20 +829,33 @@ def __init__(
# Save or instantiate the transport.
# Ordinarily, we provide the transport, but allowing a custom transport
# instance provides an extensibility point for unusual situations.
- if isinstance(transport, BigtableTableAdminTransport):
+ transport_provided = isinstance(transport, BigtableTableAdminTransport)
+ if transport_provided:
# transport is a BigtableTableAdminTransport instance.
- if credentials or client_options.credentials_file or api_key_value:
+ if credentials or self._client_options.credentials_file or api_key_value:
raise ValueError(
"When providing a transport instance, "
"provide its credentials directly."
)
- if client_options.scopes:
+ if self._client_options.scopes:
raise ValueError(
"When providing a transport instance, provide its scopes "
"directly."
)
- self._transport = transport
- else:
+ self._transport = cast(BigtableTableAdminTransport, transport)
+ self._api_endpoint = self._transport.host
+
+ self._api_endpoint = (
+ self._api_endpoint
+ or BaseBigtableTableAdminClient._get_api_endpoint(
+ self._client_options.api_endpoint,
+ self._client_cert_source,
+ self._universe_domain,
+ self._use_mtls_endpoint,
+ )
+ )
+
+ if not transport_provided:
import google.auth._default # type: ignore
if api_key_value and hasattr(
@@ -540,33 +865,92 @@ def __init__(
api_key_value
)
- Transport = type(self).get_transport_class(transport)
- self._transport = Transport(
+ transport_init: Union[
+ Type[BigtableTableAdminTransport],
+ Callable[..., BigtableTableAdminTransport],
+ ] = (
+ BaseBigtableTableAdminClient.get_transport_class(transport)
+ if isinstance(transport, str) or transport is None
+ else cast(Callable[..., BigtableTableAdminTransport], transport)
+ )
+ # initialize with the provided callable or the passed in class
+ self._transport = transport_init(
credentials=credentials,
- credentials_file=client_options.credentials_file,
- host=api_endpoint,
- scopes=client_options.scopes,
- client_cert_source_for_mtls=client_cert_source_func,
- quota_project_id=client_options.quota_project_id,
+ credentials_file=self._client_options.credentials_file,
+ host=self._api_endpoint,
+ scopes=self._client_options.scopes,
+ client_cert_source_for_mtls=self._client_cert_source,
+ quota_project_id=self._client_options.quota_project_id,
client_info=client_info,
always_use_jwt_access=True,
+ api_audience=self._client_options.api_audience,
)
+ if "async" not in str(self._transport):
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ std_logging.DEBUG
+ ): # pragma: NO COVER
+ _LOGGER.debug(
+ "Created client `google.bigtable.admin_v2.BaseBigtableTableAdminClient`.",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "universeDomain": getattr(
+ self._transport._credentials, "universe_domain", ""
+ ),
+ "credentialsType": f"{type(self._transport._credentials).__module__}.{type(self._transport._credentials).__qualname__}",
+ "credentialsInfo": getattr(
+ self.transport._credentials, "get_cred_info", lambda: None
+ )(),
+ }
+ if hasattr(self._transport, "_credentials")
+ else {
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "credentialsType": None,
+ },
+ )
+
def create_table(
self,
- request: Union[bigtable_table_admin.CreateTableRequest, dict] = None,
+ request: Optional[Union[bigtable_table_admin.CreateTableRequest, dict]] = None,
*,
- parent: str = None,
- table_id: str = None,
- table: gba_table.Table = None,
+ parent: Optional[str] = None,
+ table_id: Optional[str] = None,
+ table: Optional[gba_table.Table] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> gba_table.Table:
r"""Creates a new table in the specified instance.
The table can be created with a full set of initial
column families, specified in the request.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_create_table():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.CreateTableRequest(
+ parent="parent_value",
+ table_id="table_id_value",
+ )
+
+ # Make the request
+ response = client.create_table(request=request)
+
+ # Handle the response
+ print(response)
+
Args:
request (Union[google.cloud.bigtable_admin_v2.types.CreateTableRequest, dict]):
The request object. Request message for
@@ -596,8 +980,10 @@ def create_table(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_admin_v2.types.Table:
@@ -608,19 +994,20 @@ def create_table(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([parent, table_id, table])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent, table_id, table]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_table_admin.CreateTableRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
if not isinstance(request, bigtable_table_admin.CreateTableRequest):
request = bigtable_table_admin.CreateTableRequest(request)
# If we have keyword arguments corresponding to fields on the
@@ -642,6 +1029,9 @@ def create_table(
gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -655,20 +1045,21 @@ def create_table(
def create_table_from_snapshot(
self,
- request: Union[
- bigtable_table_admin.CreateTableFromSnapshotRequest, dict
+ request: Optional[
+ Union[bigtable_table_admin.CreateTableFromSnapshotRequest, dict]
] = None,
*,
- parent: str = None,
- table_id: str = None,
- source_snapshot: str = None,
+ parent: Optional[str] = None,
+ table_id: Optional[str] = None,
+ source_snapshot: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> operation.Operation:
r"""Creates a new table from the specified snapshot. The
target table must not exist. The snapshot and the table
must be in the same instance.
+
Note: This is a private alpha release of Cloud Bigtable
snapshots. This feature is not currently available to
most Cloud Bigtable customers. This feature might be
@@ -676,10 +1067,43 @@ def create_table_from_snapshot(
recommended for production use. It is not subject to any
SLA or deprecation policy.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_create_table_from_snapshot():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.CreateTableFromSnapshotRequest(
+ parent="parent_value",
+ table_id="table_id_value",
+ source_snapshot="source_snapshot_value",
+ )
+
+ # Make the request
+ operation = client.create_table_from_snapshot(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = operation.result()
+
+ # Handle the response
+ print(response)
+
Args:
request (Union[google.cloud.bigtable_admin_v2.types.CreateTableFromSnapshotRequest, dict]):
The request object. Request message for
[google.bigtable.admin.v2.BigtableTableAdmin.CreateTableFromSnapshot][google.bigtable.admin.v2.BigtableTableAdmin.CreateTableFromSnapshot]
+
Note: This is a private alpha release of Cloud Bigtable
snapshots. This feature is not currently available to
most Cloud Bigtable customers. This feature might be
@@ -714,8 +1138,10 @@ def create_table_from_snapshot(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.api_core.operation.Operation:
@@ -727,19 +1153,20 @@ def create_table_from_snapshot(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([parent, table_id, source_snapshot])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent, table_id, source_snapshot]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_table_admin.CreateTableFromSnapshotRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
if not isinstance(request, bigtable_table_admin.CreateTableFromSnapshotRequest):
request = bigtable_table_admin.CreateTableFromSnapshotRequest(request)
# If we have keyword arguments corresponding to fields on the
@@ -763,6 +1190,9 @@ def create_table_from_snapshot(
gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -784,15 +1214,42 @@ def create_table_from_snapshot(
def list_tables(
self,
- request: Union[bigtable_table_admin.ListTablesRequest, dict] = None,
+ request: Optional[Union[bigtable_table_admin.ListTablesRequest, dict]] = None,
*,
- parent: str = None,
+ parent: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> pagers.ListTablesPager:
r"""Lists all tables served from a specified instance.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_list_tables():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.ListTablesRequest(
+ parent="parent_value",
+ )
+
+ # Make the request
+ page_result = client.list_tables(request=request)
+
+ # Handle the response
+ for response in page_result:
+ print(response)
+
Args:
request (Union[google.cloud.bigtable_admin_v2.types.ListTablesRequest, dict]):
The request object. Request message for
@@ -808,8 +1265,10 @@ def list_tables(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_admin_v2.services.bigtable_table_admin.pagers.ListTablesPager:
@@ -821,19 +1280,20 @@ def list_tables(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([parent])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_table_admin.ListTablesRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
if not isinstance(request, bigtable_table_admin.ListTablesRequest):
request = bigtable_table_admin.ListTablesRequest(request)
# If we have keyword arguments corresponding to fields on the
@@ -851,6 +1311,9 @@ def list_tables(
gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -865,6 +1328,8 @@ def list_tables(
method=rpc,
request=request,
response=response,
+ retry=retry,
+ timeout=timeout,
metadata=metadata,
)
@@ -873,15 +1338,41 @@ def list_tables(
def get_table(
self,
- request: Union[bigtable_table_admin.GetTableRequest, dict] = None,
+ request: Optional[Union[bigtable_table_admin.GetTableRequest, dict]] = None,
*,
- name: str = None,
+ name: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> table.Table:
r"""Gets metadata information about the specified table.
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_get_table():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.GetTableRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ response = client.get_table(request=request)
+
+ # Handle the response
+ print(response)
+
Args:
request (Union[google.cloud.bigtable_admin_v2.types.GetTableRequest, dict]):
The request object. Request message for
@@ -897,8 +1388,10 @@ def get_table(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_admin_v2.types.Table:
@@ -909,19 +1402,20 @@ def get_table(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_table_admin.GetTableRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
if not isinstance(request, bigtable_table_admin.GetTableRequest):
request = bigtable_table_admin.GetTableRequest(request)
# If we have keyword arguments corresponding to fields on the
@@ -939,6 +1433,9 @@ def get_table(
gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -950,157 +1447,349 @@ def get_table(
# Done; return the response.
return response
- def delete_table(
+ def update_table(
self,
- request: Union[bigtable_table_admin.DeleteTableRequest, dict] = None,
+ request: Optional[Union[bigtable_table_admin.UpdateTableRequest, dict]] = None,
*,
- name: str = None,
+ table: Optional[gba_table.Table] = None,
+ update_mask: Optional[field_mask_pb2.FieldMask] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
- ) -> None:
- r"""Permanently deletes a specified table and all of its
- data.
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operation.Operation:
+ r"""Updates a specified table.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_update_table():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.UpdateTableRequest(
+ )
+
+ # Make the request
+ operation = client.update_table(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = operation.result()
+
+ # Handle the response
+ print(response)
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.DeleteTableRequest, dict]):
- The request object. Request message for
- [google.bigtable.admin.v2.BigtableTableAdmin.DeleteTable][google.bigtable.admin.v2.BigtableTableAdmin.DeleteTable]
- name (str):
- Required. The unique name of the table to be deleted.
- Values are of the form
- ``projects/{project}/instances/{instance}/tables/{table}``.
+ request (Union[google.cloud.bigtable_admin_v2.types.UpdateTableRequest, dict]):
+ The request object. The request for
+ [UpdateTable][google.bigtable.admin.v2.BigtableTableAdmin.UpdateTable].
+ table (google.cloud.bigtable_admin_v2.types.Table):
+ Required. The table to update. The table's ``name``
+ field is used to identify the table to update.
- This corresponds to the ``name`` field
+ This corresponds to the ``table`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ update_mask (google.protobuf.field_mask_pb2.FieldMask):
+ Required. The list of fields to update. A mask
+ specifying which fields (e.g. ``change_stream_config``)
+ in the ``table`` field should be updated. This mask is
+ relative to the ``table`` field, not to the request
+ message. The wildcard (\*) path is currently not
+ supported. Currently UpdateTable is only supported for
+ the following fields:
+
+ - ``change_stream_config``
+ - ``change_stream_config.retention_period``
+ - ``deletion_protection``
+ - ``row_key_schema``
+
+ If ``column_families`` is set in ``update_mask``, it
+ will return an UNIMPLEMENTED error.
+
+ This corresponds to the ``update_mask`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.api_core.operation.Operation:
+ An object representing a long-running operation.
+
+ The result type for the operation will be :class:`google.cloud.bigtable_admin_v2.types.Table` A collection of user data indexed by row, column, and timestamp.
+ Each table is served using the resources of its
+ parent cluster.
+
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [table, update_mask]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_table_admin.DeleteTableRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
- if not isinstance(request, bigtable_table_admin.DeleteTableRequest):
- request = bigtable_table_admin.DeleteTableRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.UpdateTableRequest):
+ request = bigtable_table_admin.UpdateTableRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
- if name is not None:
- request.name = name
+ if table is not None:
+ request.table = table
+ if update_mask is not None:
+ request.update_mask = update_mask
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = self._transport._wrapped_methods[self._transport.delete_table]
+ rpc = self._transport._wrapped_methods[self._transport.update_table]
# Certain fields should be provided within the metadata header;
# add these here.
metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ gapic_v1.routing_header.to_grpc_metadata(
+ (("table.name", request.table.name),)
+ ),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
- rpc(
+ response = rpc(
request,
retry=retry,
timeout=timeout,
metadata=metadata,
)
- def modify_column_families(
+ # Wrap the response in an operation future.
+ response = operation.from_gapic(
+ response,
+ self._transport.operations_client,
+ gba_table.Table,
+ metadata_type=bigtable_table_admin.UpdateTableMetadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def delete_table(
self,
- request: Union[bigtable_table_admin.ModifyColumnFamiliesRequest, dict] = None,
+ request: Optional[Union[bigtable_table_admin.DeleteTableRequest, dict]] = None,
*,
- name: str = None,
- modifications: Sequence[
- bigtable_table_admin.ModifyColumnFamiliesRequest.Modification
- ] = None,
+ name: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
- ) -> table.Table:
- r"""Performs a series of column family modifications on
- the specified table. Either all or none of the
- modifications will occur before this method returns, but
- data requests received prior to that point may see a
- table where only some modifications have taken effect.
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> None:
+ r"""Permanently deletes a specified table and all of its
+ data.
- Args:
- request (Union[google.cloud.bigtable_admin_v2.types.ModifyColumnFamiliesRequest, dict]):
- The request object. Request message for
- [google.bigtable.admin.v2.BigtableTableAdmin.ModifyColumnFamilies][google.bigtable.admin.v2.BigtableTableAdmin.ModifyColumnFamilies]
- name (str):
- Required. The unique name of the table whose families
- should be modified. Values are of the form
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_delete_table():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.DeleteTableRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ client.delete_table(request=request)
+
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.types.DeleteTableRequest, dict]):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.DeleteTable][google.bigtable.admin.v2.BigtableTableAdmin.DeleteTable]
+ name (str):
+ Required. The unique name of the table to be deleted.
+ Values are of the form
``projects/{project}/instances/{instance}/tables/{table}``.
This corresponds to the ``name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- modifications (Sequence[google.cloud.bigtable_admin_v2.types.ModifyColumnFamiliesRequest.Modification]):
- Required. Modifications to be
- atomically applied to the specified
- table's families. Entries are applied in
- order, meaning that earlier
- modifications can be masked by later
- ones (in the case of repeated updates to
- the same family, for example).
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
- This corresponds to the ``modifications`` field
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.DeleteTableRequest):
+ request = bigtable_table_admin.DeleteTableRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.delete_table]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
+ # Send the request.
+ rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ def undelete_table(
+ self,
+ request: Optional[
+ Union[bigtable_table_admin.UndeleteTableRequest, dict]
+ ] = None,
+ *,
+ name: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operation.Operation:
+ r"""Restores a specified table which was accidentally
+ deleted.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_undelete_table():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.UndeleteTableRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ operation = client.undelete_table(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = operation.result()
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.types.UndeleteTableRequest, dict]):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.UndeleteTable][google.bigtable.admin.v2.BigtableTableAdmin.UndeleteTable]
+ name (str):
+ Required. The unique name of the table to be restored.
+ Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}``.
+
+ This corresponds to the ``name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
- google.cloud.bigtable_admin_v2.types.Table:
- A collection of user data indexed by
- row, column, and timestamp. Each table
- is served using the resources of its
- parent cluster.
+ google.api_core.operation.Operation:
+ An object representing a long-running operation.
+
+ The result type for the operation will be :class:`google.cloud.bigtable_admin_v2.types.Table` A collection of user data indexed by row, column, and timestamp.
+ Each table is served using the resources of its
+ parent cluster.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name, modifications])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_table_admin.ModifyColumnFamiliesRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
- if not isinstance(request, bigtable_table_admin.ModifyColumnFamiliesRequest):
- request = bigtable_table_admin.ModifyColumnFamiliesRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.UndeleteTableRequest):
+ request = bigtable_table_admin.UndeleteTableRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
if name is not None:
request.name = name
- if modifications is not None:
- request.modifications = modifications
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = self._transport._wrapped_methods[self._transport.modify_column_families]
+ rpc = self._transport._wrapped_methods[self._transport.undelete_table]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -1108,6 +1797,9 @@ def modify_column_families(
gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -1116,134 +1808,272 @@ def modify_column_families(
metadata=metadata,
)
+ # Wrap the response in an operation future.
+ response = operation.from_gapic(
+ response,
+ self._transport.operations_client,
+ table.Table,
+ metadata_type=bigtable_table_admin.UndeleteTableMetadata,
+ )
+
# Done; return the response.
return response
- def drop_row_range(
+ def create_authorized_view(
self,
- request: Union[bigtable_table_admin.DropRowRangeRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_table_admin.CreateAuthorizedViewRequest, dict]
+ ] = None,
*,
+ parent: Optional[str] = None,
+ authorized_view: Optional[table.AuthorizedView] = None,
+ authorized_view_id: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
- ) -> None:
- r"""Permanently drop/delete a row range from a specified
- table. The request can specify whether to delete all
- rows in a table, or only those that match a particular
- prefix.
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operation.Operation:
+ r"""Creates a new AuthorizedView in a table.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_create_authorized_view():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.CreateAuthorizedViewRequest(
+ parent="parent_value",
+ authorized_view_id="authorized_view_id_value",
+ )
+
+ # Make the request
+ operation = client.create_authorized_view(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = operation.result()
+
+ # Handle the response
+ print(response)
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.DropRowRangeRequest, dict]):
- The request object. Request message for
- [google.bigtable.admin.v2.BigtableTableAdmin.DropRowRange][google.bigtable.admin.v2.BigtableTableAdmin.DropRowRange]
+ request (Union[google.cloud.bigtable_admin_v2.types.CreateAuthorizedViewRequest, dict]):
+ The request object. The request for
+ [CreateAuthorizedView][google.bigtable.admin.v2.BigtableTableAdmin.CreateAuthorizedView]
+ parent (str):
+ Required. This is the name of the table the
+ AuthorizedView belongs to. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}``.
+
+ This corresponds to the ``parent`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ authorized_view (google.cloud.bigtable_admin_v2.types.AuthorizedView):
+ Required. The AuthorizedView to
+ create.
+
+ This corresponds to the ``authorized_view`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ authorized_view_id (str):
+ Required. The id of the AuthorizedView to create. This
+ AuthorizedView must not already exist. The
+ ``authorized_view_id`` appended to ``parent`` forms the
+ full AuthorizedView name of the form
+ ``projects/{project}/instances/{instance}/tables/{table}/authorizedView/{authorized_view}``.
+
+ This corresponds to the ``authorized_view_id`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.api_core.operation.Operation:
+ An object representing a long-running operation.
+
+ The result type for the operation will be :class:`google.cloud.bigtable_admin_v2.types.AuthorizedView` AuthorizedViews represent subsets of a particular Cloud Bigtable table. Users
+ can configure access to each Authorized View
+ independently from the table and use the existing
+ Data APIs to access the subset of data.
+
"""
# Create or coerce a protobuf request object.
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_table_admin.DropRowRangeRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
- if not isinstance(request, bigtable_table_admin.DropRowRangeRequest):
- request = bigtable_table_admin.DropRowRangeRequest(request)
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent, authorized_view, authorized_view_id]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.CreateAuthorizedViewRequest):
+ request = bigtable_table_admin.CreateAuthorizedViewRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if parent is not None:
+ request.parent = parent
+ if authorized_view is not None:
+ request.authorized_view = authorized_view
+ if authorized_view_id is not None:
+ request.authorized_view_id = authorized_view_id
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = self._transport._wrapped_methods[self._transport.drop_row_range]
+ rpc = self._transport._wrapped_methods[self._transport.create_authorized_view]
# Certain fields should be provided within the metadata header;
# add these here.
metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
- rpc(
+ response = rpc(
request,
retry=retry,
timeout=timeout,
metadata=metadata,
)
- def generate_consistency_token(
+ # Wrap the response in an operation future.
+ response = operation.from_gapic(
+ response,
+ self._transport.operations_client,
+ table.AuthorizedView,
+ metadata_type=bigtable_table_admin.CreateAuthorizedViewMetadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def list_authorized_views(
self,
- request: Union[
- bigtable_table_admin.GenerateConsistencyTokenRequest, dict
+ request: Optional[
+ Union[bigtable_table_admin.ListAuthorizedViewsRequest, dict]
] = None,
*,
- name: str = None,
+ parent: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
- ) -> bigtable_table_admin.GenerateConsistencyTokenResponse:
- r"""Generates a consistency token for a Table, which can
- be used in CheckConsistency to check whether mutations
- to the table that finished before this call started have
- been replicated. The tokens will be available for 90
- days.
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> pagers.ListAuthorizedViewsPager:
+ r"""Lists all AuthorizedViews from a specific table.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_list_authorized_views():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.ListAuthorizedViewsRequest(
+ parent="parent_value",
+ )
+
+ # Make the request
+ page_result = client.list_authorized_views(request=request)
+
+ # Handle the response
+ for response in page_result:
+ print(response)
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.GenerateConsistencyTokenRequest, dict]):
+ request (Union[google.cloud.bigtable_admin_v2.types.ListAuthorizedViewsRequest, dict]):
The request object. Request message for
- [google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken][google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken]
- name (str):
- Required. The unique name of the Table for which to
- create a consistency token. Values are of the form
+ [google.bigtable.admin.v2.BigtableTableAdmin.ListAuthorizedViews][google.bigtable.admin.v2.BigtableTableAdmin.ListAuthorizedViews]
+ parent (str):
+ Required. The unique name of the table for which
+ AuthorizedViews should be listed. Values are of the form
``projects/{project}/instances/{instance}/tables/{table}``.
- This corresponds to the ``name`` field
+ This corresponds to the ``parent`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
- google.cloud.bigtable_admin_v2.types.GenerateConsistencyTokenResponse:
+ google.cloud.bigtable_admin_v2.services.bigtable_table_admin.pagers.ListAuthorizedViewsPager:
Response message for
- [google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken][google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken]
+ [google.bigtable.admin.v2.BigtableTableAdmin.ListAuthorizedViews][google.bigtable.admin.v2.BigtableTableAdmin.ListAuthorizedViews]
+
+ Iterating over this object will yield results and
+ resolve additional pages automatically.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_table_admin.GenerateConsistencyTokenRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
- if not isinstance(
- request, bigtable_table_admin.GenerateConsistencyTokenRequest
- ):
- request = bigtable_table_admin.GenerateConsistencyTokenRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.ListAuthorizedViewsRequest):
+ request = bigtable_table_admin.ListAuthorizedViewsRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
- if name is not None:
- request.name = name
+ if parent is not None:
+ request.parent = parent
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = self._transport._wrapped_methods[
- self._transport.generate_consistency_token
- ]
+ rpc = self._transport._wrapped_methods[self._transport.list_authorized_views]
# Certain fields should be provided within the metadata header;
# add these here.
metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -1252,81 +2082,114 @@ def generate_consistency_token(
metadata=metadata,
)
+ # This method is paged; wrap the response in a pager, which provides
+ # an `__iter__` convenience method.
+ response = pagers.ListAuthorizedViewsPager(
+ method=rpc,
+ request=request,
+ response=response,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
# Done; return the response.
return response
- def check_consistency(
+ def get_authorized_view(
self,
- request: Union[bigtable_table_admin.CheckConsistencyRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_table_admin.GetAuthorizedViewRequest, dict]
+ ] = None,
*,
- name: str = None,
- consistency_token: str = None,
+ name: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
- ) -> bigtable_table_admin.CheckConsistencyResponse:
- r"""Checks replication consistency based on a consistency
- token, that is, if replication has caught up based on
- the conditions specified in the token and the check
- request.
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> table.AuthorizedView:
+ r"""Gets information from a specified AuthorizedView.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_get_authorized_view():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.GetAuthorizedViewRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ response = client.get_authorized_view(request=request)
+
+ # Handle the response
+ print(response)
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.CheckConsistencyRequest, dict]):
+ request (Union[google.cloud.bigtable_admin_v2.types.GetAuthorizedViewRequest, dict]):
The request object. Request message for
- [google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency][google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency]
+ [google.bigtable.admin.v2.BigtableTableAdmin.GetAuthorizedView][google.bigtable.admin.v2.BigtableTableAdmin.GetAuthorizedView]
name (str):
- Required. The unique name of the Table for which to
- check replication consistency. Values are of the form
- ``projects/{project}/instances/{instance}/tables/{table}``.
+ Required. The unique name of the requested
+ AuthorizedView. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}/authorizedViews/{authorized_view}``.
This corresponds to the ``name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- consistency_token (str):
- Required. The token created using
- GenerateConsistencyToken for the Table.
-
- This corresponds to the ``consistency_token`` field
- on the ``request`` instance; if ``request`` is provided, this
- should not be set.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
- google.cloud.bigtable_admin_v2.types.CheckConsistencyResponse:
- Response message for
- [google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency][google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency]
+ google.cloud.bigtable_admin_v2.types.AuthorizedView:
+ AuthorizedViews represent subsets of
+ a particular Cloud Bigtable table. Users
+ can configure access to each Authorized
+ View independently from the table and
+ use the existing Data APIs to access the
+ subset of data.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name, consistency_token])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_table_admin.CheckConsistencyRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
- if not isinstance(request, bigtable_table_admin.CheckConsistencyRequest):
- request = bigtable_table_admin.CheckConsistencyRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.GetAuthorizedViewRequest):
+ request = bigtable_table_admin.GetAuthorizedViewRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
if name is not None:
request.name = name
- if consistency_token is not None:
- request.consistency_token = consistency_token
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = self._transport._wrapped_methods[self._transport.check_consistency]
+ rpc = self._transport._wrapped_methods[self._transport.get_authorized_view]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -1334,6 +2197,9 @@ def check_consistency(
gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -1345,128 +2211,132 @@ def check_consistency(
# Done; return the response.
return response
- def snapshot_table(
+ def update_authorized_view(
self,
- request: Union[bigtable_table_admin.SnapshotTableRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_table_admin.UpdateAuthorizedViewRequest, dict]
+ ] = None,
*,
- name: str = None,
- cluster: str = None,
- snapshot_id: str = None,
- description: str = None,
+ authorized_view: Optional[table.AuthorizedView] = None,
+ update_mask: Optional[field_mask_pb2.FieldMask] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> operation.Operation:
- r"""Creates a new snapshot in the specified cluster from
- the specified source table. The cluster and the table
- must be in the same instance.
- Note: This is a private alpha release of Cloud Bigtable
- snapshots. This feature is not currently available to
- most Cloud Bigtable customers. This feature might be
- changed in backward-incompatible ways and is not
- recommended for production use. It is not subject to any
- SLA or deprecation policy.
+ r"""Updates an AuthorizedView in a table.
- Args:
- request (Union[google.cloud.bigtable_admin_v2.types.SnapshotTableRequest, dict]):
- The request object. Request message for
- [google.bigtable.admin.v2.BigtableTableAdmin.SnapshotTable][google.bigtable.admin.v2.BigtableTableAdmin.SnapshotTable]
- Note: This is a private alpha release of Cloud Bigtable
- snapshots. This feature is not currently available to
- most Cloud Bigtable customers. This feature might be
- changed in backward-incompatible ways and is not
- recommended for production use. It is not subject to any
- SLA or deprecation policy.
- name (str):
- Required. The unique name of the table to have the
- snapshot taken. Values are of the form
- ``projects/{project}/instances/{instance}/tables/{table}``.
+ .. code-block:: python
- This corresponds to the ``name`` field
- on the ``request`` instance; if ``request`` is provided, this
- should not be set.
- cluster (str):
- Required. The name of the cluster where the snapshot
- will be created in. Values are of the form
- ``projects/{project}/instances/{instance}/clusters/{cluster}``.
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
- This corresponds to the ``cluster`` field
- on the ``request`` instance; if ``request`` is provided, this
- should not be set.
- snapshot_id (str):
- Required. The ID by which the new snapshot should be
- referred to within the parent cluster, e.g.,
- ``mysnapshot`` of the form:
- ``[_a-zA-Z0-9][-_.a-zA-Z0-9]*`` rather than
- ``projects/{project}/instances/{instance}/clusters/{cluster}/snapshots/mysnapshot``.
+ def sample_update_authorized_view():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
- This corresponds to the ``snapshot_id`` field
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.UpdateAuthorizedViewRequest(
+ )
+
+ # Make the request
+ operation = client.update_authorized_view(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = operation.result()
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.types.UpdateAuthorizedViewRequest, dict]):
+ The request object. The request for
+ [UpdateAuthorizedView][google.bigtable.admin.v2.BigtableTableAdmin.UpdateAuthorizedView].
+ authorized_view (google.cloud.bigtable_admin_v2.types.AuthorizedView):
+ Required. The AuthorizedView to update. The ``name`` in
+ ``authorized_view`` is used to identify the
+ AuthorizedView. AuthorizedView name must in this format:
+ ``projects/{project}/instances/{instance}/tables/{table}/authorizedViews/{authorized_view}``.
+
+ This corresponds to the ``authorized_view`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- description (str):
- Description of the snapshot.
- This corresponds to the ``description`` field
+ update_mask (google.protobuf.field_mask_pb2.FieldMask):
+ Optional. The list of fields to update. A mask
+ specifying which fields in the AuthorizedView resource
+ should be updated. This mask is relative to the
+ AuthorizedView resource, not to the request message. A
+ field will be overwritten if it is in the mask. If
+ empty, all fields set in the request will be
+ overwritten. A special value ``*`` means to overwrite
+ all fields (including fields not set in the request).
+
+ This corresponds to the ``update_mask`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.api_core.operation.Operation:
An object representing a long-running operation.
- The result type for the operation will be :class:`google.cloud.bigtable_admin_v2.types.Snapshot` A snapshot of a table at a particular time. A snapshot can be used as a
- checkpoint for data restoration or a data source for
- a new table.
-
- Note: This is a private alpha release of Cloud
- Bigtable snapshots. This feature is not currently
- available to most Cloud Bigtable customers. This
- feature might be changed in backward-incompatible
- ways and is not recommended for production use. It is
- not subject to any SLA or deprecation policy.
+ The result type for the operation will be :class:`google.cloud.bigtable_admin_v2.types.AuthorizedView` AuthorizedViews represent subsets of a particular Cloud Bigtable table. Users
+ can configure access to each Authorized View
+ independently from the table and use the existing
+ Data APIs to access the subset of data.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name, cluster, snapshot_id, description])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [authorized_view, update_mask]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_table_admin.SnapshotTableRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
- if not isinstance(request, bigtable_table_admin.SnapshotTableRequest):
- request = bigtable_table_admin.SnapshotTableRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.UpdateAuthorizedViewRequest):
+ request = bigtable_table_admin.UpdateAuthorizedViewRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
- if name is not None:
- request.name = name
- if cluster is not None:
- request.cluster = cluster
- if snapshot_id is not None:
- request.snapshot_id = snapshot_id
- if description is not None:
- request.description = description
+ if authorized_view is not None:
+ request.authorized_view = authorized_view
+ if update_mask is not None:
+ request.update_mask = update_mask
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = self._transport._wrapped_methods[self._transport.snapshot_table]
+ rpc = self._transport._wrapped_methods[self._transport.update_authorized_view]
# Certain fields should be provided within the metadata header;
# add these here.
metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ gapic_v1.routing_header.to_grpc_metadata(
+ (("authorized_view.name", request.authorized_view.name),)
+ ),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -1479,45 +2349,57 @@ def snapshot_table(
response = operation.from_gapic(
response,
self._transport.operations_client,
- table.Snapshot,
- metadata_type=bigtable_table_admin.SnapshotTableMetadata,
+ table.AuthorizedView,
+ metadata_type=bigtable_table_admin.UpdateAuthorizedViewMetadata,
)
# Done; return the response.
return response
- def get_snapshot(
+ def delete_authorized_view(
self,
- request: Union[bigtable_table_admin.GetSnapshotRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_table_admin.DeleteAuthorizedViewRequest, dict]
+ ] = None,
*,
- name: str = None,
+ name: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
- ) -> table.Snapshot:
- r"""Gets metadata information about the specified
- snapshot.
- Note: This is a private alpha release of Cloud Bigtable
- snapshots. This feature is not currently available to
- most Cloud Bigtable customers. This feature might be
- changed in backward-incompatible ways and is not
- recommended for production use. It is not subject to any
- SLA or deprecation policy.
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> None:
+ r"""Permanently deletes a specified AuthorizedView.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_delete_authorized_view():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.DeleteAuthorizedViewRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ client.delete_authorized_view(request=request)
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.GetSnapshotRequest, dict]):
+ request (Union[google.cloud.bigtable_admin_v2.types.DeleteAuthorizedViewRequest, dict]):
The request object. Request message for
- [google.bigtable.admin.v2.BigtableTableAdmin.GetSnapshot][google.bigtable.admin.v2.BigtableTableAdmin.GetSnapshot]
- Note: This is a private alpha release of Cloud Bigtable
- snapshots. This feature is not currently available to
- most Cloud Bigtable customers. This feature might be
- changed in backward-incompatible ways and is not
- recommended for production use. It is not subject to any
- SLA or deprecation policy.
+ [google.bigtable.admin.v2.BigtableTableAdmin.DeleteAuthorizedView][google.bigtable.admin.v2.BigtableTableAdmin.DeleteAuthorizedView]
name (str):
- Required. The unique name of the requested snapshot.
- Values are of the form
- ``projects/{project}/instances/{instance}/clusters/{cluster}/snapshots/{snapshot}``.
+ Required. The unique name of the AuthorizedView to be
+ deleted. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}/authorizedViews/{authorized_view}``.
This corresponds to the ``name`` field
on the ``request`` instance; if ``request`` is provided, this
@@ -1525,41 +2407,28 @@ def get_snapshot(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
-
- Returns:
- google.cloud.bigtable_admin_v2.types.Snapshot:
- A snapshot of a table at a particular
- time. A snapshot can be used as a
- checkpoint for data restoration or a
- data source for a new table.
- Note: This is a private alpha release of
- Cloud Bigtable snapshots. This feature
- is not currently available to most Cloud
- Bigtable customers. This feature might
- be changed in backward-incompatible ways
- and is not recommended for production
- use. It is not subject to any SLA or
- deprecation policy.
-
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_table_admin.GetSnapshotRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
- if not isinstance(request, bigtable_table_admin.GetSnapshotRequest):
- request = bigtable_table_admin.GetSnapshotRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.DeleteAuthorizedViewRequest):
+ request = bigtable_table_admin.DeleteAuthorizedViewRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
if name is not None:
@@ -1567,7 +2436,7 @@ def get_snapshot(
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = self._transport._wrapped_methods[self._transport.get_snapshot]
+ rpc = self._transport._wrapped_methods[self._transport.delete_authorized_view]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -1575,109 +2444,142 @@ def get_snapshot(
gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
- response = rpc(
+ rpc(
request,
retry=retry,
timeout=timeout,
metadata=metadata,
)
- # Done; return the response.
- return response
-
- def list_snapshots(
+ def modify_column_families(
self,
- request: Union[bigtable_table_admin.ListSnapshotsRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_table_admin.ModifyColumnFamiliesRequest, dict]
+ ] = None,
*,
- parent: str = None,
+ name: Optional[str] = None,
+ modifications: Optional[
+ MutableSequence[
+ bigtable_table_admin.ModifyColumnFamiliesRequest.Modification
+ ]
+ ] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
- ) -> pagers.ListSnapshotsPager:
- r"""Lists all snapshots associated with the specified
- cluster.
- Note: This is a private alpha release of Cloud Bigtable
- snapshots. This feature is not currently available to
- most Cloud Bigtable customers. This feature might be
- changed in backward-incompatible ways and is not
- recommended for production use. It is not subject to any
- SLA or deprecation policy.
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> table.Table:
+ r"""Performs a series of column family modifications on
+ the specified table. Either all or none of the
+ modifications will occur before this method returns, but
+ data requests received prior to that point may see a
+ table where only some modifications have taken effect.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_modify_column_families():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.ModifyColumnFamiliesRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ response = client.modify_column_families(request=request)
+
+ # Handle the response
+ print(response)
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.ListSnapshotsRequest, dict]):
+ request (Union[google.cloud.bigtable_admin_v2.types.ModifyColumnFamiliesRequest, dict]):
The request object. Request message for
- [google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots][google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots]
- Note: This is a private alpha release of Cloud Bigtable
- snapshots. This feature is not currently available to
- most Cloud Bigtable customers. This feature might be
- changed in backward-incompatible ways and is not
- recommended for production use. It is not subject to any
- SLA or deprecation policy.
- parent (str):
- Required. The unique name of the cluster for which
- snapshots should be listed. Values are of the form
- ``projects/{project}/instances/{instance}/clusters/{cluster}``.
- Use ``{cluster} = '-'`` to list snapshots for all
- clusters in an instance, e.g.,
- ``projects/{project}/instances/{instance}/clusters/-``.
+ [google.bigtable.admin.v2.BigtableTableAdmin.ModifyColumnFamilies][google.bigtable.admin.v2.BigtableTableAdmin.ModifyColumnFamilies]
+ name (str):
+ Required. The unique name of the table whose families
+ should be modified. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}``.
- This corresponds to the ``parent`` field
+ This corresponds to the ``name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ modifications (MutableSequence[google.cloud.bigtable_admin_v2.types.ModifyColumnFamiliesRequest.Modification]):
+ Required. Modifications to be
+ atomically applied to the specified
+ table's families. Entries are applied in
+ order, meaning that earlier
+ modifications can be masked by later
+ ones (in the case of repeated updates to
+ the same family, for example).
+
+ This corresponds to the ``modifications`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
- google.cloud.bigtable_admin_v2.services.bigtable_table_admin.pagers.ListSnapshotsPager:
- Response message for
- [google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots][google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots]
-
- Note: This is a private alpha release of Cloud
- Bigtable snapshots. This feature is not currently
- available to most Cloud Bigtable customers. This
- feature might be changed in backward-incompatible
- ways and is not recommended for production use. It is
- not subject to any SLA or deprecation policy.
-
- Iterating over this object will yield results and
- resolve additional pages automatically.
+ google.cloud.bigtable_admin_v2.types.Table:
+ A collection of user data indexed by
+ row, column, and timestamp. Each table
+ is served using the resources of its
+ parent cluster.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([parent])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name, modifications]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_table_admin.ListSnapshotsRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
- if not isinstance(request, bigtable_table_admin.ListSnapshotsRequest):
- request = bigtable_table_admin.ListSnapshotsRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.ModifyColumnFamiliesRequest):
+ request = bigtable_table_admin.ModifyColumnFamiliesRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
- if parent is not None:
- request.parent = parent
+ if name is not None:
+ request.name = name
+ if modifications is not None:
+ request.modifications = modifications
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = self._transport._wrapped_methods[self._transport.list_snapshots]
+ rpc = self._transport._wrapped_methods[self._transport.modify_column_families]
# Certain fields should be provided within the metadata header;
# add these here.
metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -1686,154 +2588,1743 @@ def list_snapshots(
metadata=metadata,
)
- # This method is paged; wrap the response in a pager, which provides
- # an `__iter__` convenience method.
- response = pagers.ListSnapshotsPager(
- method=rpc,
- request=request,
- response=response,
- metadata=metadata,
- )
-
# Done; return the response.
return response
- def delete_snapshot(
+ def drop_row_range(
self,
- request: Union[bigtable_table_admin.DeleteSnapshotRequest, dict] = None,
+ request: Optional[Union[bigtable_table_admin.DropRowRangeRequest, dict]] = None,
*,
- name: str = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> None:
- r"""Permanently deletes the specified snapshot.
- Note: This is a private alpha release of Cloud Bigtable
- snapshots. This feature is not currently available to
- most Cloud Bigtable customers. This feature might be
- changed in backward-incompatible ways and is not
- recommended for production use. It is not subject to any
- SLA or deprecation policy.
+ r"""Permanently drop/delete a row range from a specified
+ table. The request can specify whether to delete all
+ rows in a table, or only those that match a particular
+ prefix.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_drop_row_range():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.DropRowRangeRequest(
+ row_key_prefix=b'row_key_prefix_blob',
+ name="name_value",
+ )
+
+ # Make the request
+ client.drop_row_range(request=request)
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.DeleteSnapshotRequest, dict]):
+ request (Union[google.cloud.bigtable_admin_v2.types.DropRowRangeRequest, dict]):
The request object. Request message for
- [google.bigtable.admin.v2.BigtableTableAdmin.DeleteSnapshot][google.bigtable.admin.v2.BigtableTableAdmin.DeleteSnapshot]
- Note: This is a private alpha release of Cloud Bigtable
- snapshots. This feature is not currently available to
- most Cloud Bigtable customers. This feature might be
- changed in backward-incompatible ways and is not
- recommended for production use. It is not subject to any
- SLA or deprecation policy.
- name (str):
- Required. The unique name of the snapshot to be deleted.
+ [google.bigtable.admin.v2.BigtableTableAdmin.DropRowRange][google.bigtable.admin.v2.BigtableTableAdmin.DropRowRange]
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+ """
+ # Create or coerce a protobuf request object.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.DropRowRangeRequest):
+ request = bigtable_table_admin.DropRowRangeRequest(request)
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.drop_row_range]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
+ # Send the request.
+ rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ def generate_consistency_token(
+ self,
+ request: Optional[
+ Union[bigtable_table_admin.GenerateConsistencyTokenRequest, dict]
+ ] = None,
+ *,
+ name: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> bigtable_table_admin.GenerateConsistencyTokenResponse:
+ r"""Generates a consistency token for a Table, which can
+ be used in CheckConsistency to check whether mutations
+ to the table that finished before this call started have
+ been replicated. The tokens will be available for 90
+ days.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_generate_consistency_token():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.GenerateConsistencyTokenRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ response = client.generate_consistency_token(request=request)
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.types.GenerateConsistencyTokenRequest, dict]):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken][google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken]
+ name (str):
+ Required. The unique name of the Table for which to
+ create a consistency token. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}``.
+
+ This corresponds to the ``name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.cloud.bigtable_admin_v2.types.GenerateConsistencyTokenResponse:
+ Response message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken][google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken]
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(
+ request, bigtable_table_admin.GenerateConsistencyTokenRequest
+ ):
+ request = bigtable_table_admin.GenerateConsistencyTokenRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[
+ self._transport.generate_consistency_token
+ ]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
+ # Send the request.
+ response = rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def check_consistency(
+ self,
+ request: Optional[
+ Union[bigtable_table_admin.CheckConsistencyRequest, dict]
+ ] = None,
+ *,
+ name: Optional[str] = None,
+ consistency_token: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> bigtable_table_admin.CheckConsistencyResponse:
+ r"""Checks replication consistency based on a consistency
+ token, that is, if replication has caught up based on
+ the conditions specified in the token and the check
+ request.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_check_consistency():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.CheckConsistencyRequest(
+ name="name_value",
+ consistency_token="consistency_token_value",
+ )
+
+ # Make the request
+ response = client.check_consistency(request=request)
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.types.CheckConsistencyRequest, dict]):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency][google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency]
+ name (str):
+ Required. The unique name of the Table for which to
+ check replication consistency. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}``.
+
+ This corresponds to the ``name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ consistency_token (str):
+ Required. The token created using
+ GenerateConsistencyToken for the Table.
+
+ This corresponds to the ``consistency_token`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.cloud.bigtable_admin_v2.types.CheckConsistencyResponse:
+ Response message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency][google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency]
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name, consistency_token]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.CheckConsistencyRequest):
+ request = bigtable_table_admin.CheckConsistencyRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if name is not None:
+ request.name = name
+ if consistency_token is not None:
+ request.consistency_token = consistency_token
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.check_consistency]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
+ # Send the request.
+ response = rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def snapshot_table(
+ self,
+ request: Optional[
+ Union[bigtable_table_admin.SnapshotTableRequest, dict]
+ ] = None,
+ *,
+ name: Optional[str] = None,
+ cluster: Optional[str] = None,
+ snapshot_id: Optional[str] = None,
+ description: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operation.Operation:
+ r"""Creates a new snapshot in the specified cluster from
+ the specified source table. The cluster and the table
+ must be in the same instance.
+
+ Note: This is a private alpha release of Cloud Bigtable
+ snapshots. This feature is not currently available to
+ most Cloud Bigtable customers. This feature might be
+ changed in backward-incompatible ways and is not
+ recommended for production use. It is not subject to any
+ SLA or deprecation policy.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_snapshot_table():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.SnapshotTableRequest(
+ name="name_value",
+ cluster="cluster_value",
+ snapshot_id="snapshot_id_value",
+ )
+
+ # Make the request
+ operation = client.snapshot_table(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = operation.result()
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.types.SnapshotTableRequest, dict]):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.SnapshotTable][google.bigtable.admin.v2.BigtableTableAdmin.SnapshotTable]
+
+ Note: This is a private alpha release of Cloud Bigtable
+ snapshots. This feature is not currently available to
+ most Cloud Bigtable customers. This feature might be
+ changed in backward-incompatible ways and is not
+ recommended for production use. It is not subject to any
+ SLA or deprecation policy.
+ name (str):
+ Required. The unique name of the table to have the
+ snapshot taken. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}``.
+
+ This corresponds to the ``name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ cluster (str):
+ Required. The name of the cluster where the snapshot
+ will be created in. Values are of the form
+ ``projects/{project}/instances/{instance}/clusters/{cluster}``.
+
+ This corresponds to the ``cluster`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ snapshot_id (str):
+ Required. The ID by which the new snapshot should be
+ referred to within the parent cluster, e.g.,
+ ``mysnapshot`` of the form:
+ ``[_a-zA-Z0-9][-_.a-zA-Z0-9]*`` rather than
+ ``projects/{project}/instances/{instance}/clusters/{cluster}/snapshots/mysnapshot``.
+
+ This corresponds to the ``snapshot_id`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ description (str):
+ Description of the snapshot.
+ This corresponds to the ``description`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.api_core.operation.Operation:
+ An object representing a long-running operation.
+
+ The result type for the operation will be :class:`google.cloud.bigtable_admin_v2.types.Snapshot` A snapshot of a table at a particular time. A snapshot can be used as a
+ checkpoint for data restoration or a data source for
+ a new table.
+
+ Note: This is a private alpha release of Cloud
+ Bigtable snapshots. This feature is not currently
+ available to most Cloud Bigtable customers. This
+ feature might be changed in backward-incompatible
+ ways and is not recommended for production use. It is
+ not subject to any SLA or deprecation policy.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name, cluster, snapshot_id, description]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.SnapshotTableRequest):
+ request = bigtable_table_admin.SnapshotTableRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if name is not None:
+ request.name = name
+ if cluster is not None:
+ request.cluster = cluster
+ if snapshot_id is not None:
+ request.snapshot_id = snapshot_id
+ if description is not None:
+ request.description = description
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.snapshot_table]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
+ # Send the request.
+ response = rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Wrap the response in an operation future.
+ response = operation.from_gapic(
+ response,
+ self._transport.operations_client,
+ table.Snapshot,
+ metadata_type=bigtable_table_admin.SnapshotTableMetadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def get_snapshot(
+ self,
+ request: Optional[Union[bigtable_table_admin.GetSnapshotRequest, dict]] = None,
+ *,
+ name: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> table.Snapshot:
+ r"""Gets metadata information about the specified
+ snapshot.
+ Note: This is a private alpha release of Cloud Bigtable
+ snapshots. This feature is not currently available to
+ most Cloud Bigtable customers. This feature might be
+ changed in backward-incompatible ways and is not
+ recommended for production use. It is not subject to any
+ SLA or deprecation policy.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_get_snapshot():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.GetSnapshotRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ response = client.get_snapshot(request=request)
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.types.GetSnapshotRequest, dict]):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.GetSnapshot][google.bigtable.admin.v2.BigtableTableAdmin.GetSnapshot]
+
+ Note: This is a private alpha release of Cloud Bigtable
+ snapshots. This feature is not currently available to
+ most Cloud Bigtable customers. This feature might be
+ changed in backward-incompatible ways and is not
+ recommended for production use. It is not subject to any
+ SLA or deprecation policy.
+ name (str):
+ Required. The unique name of the requested snapshot.
+ Values are of the form
+ ``projects/{project}/instances/{instance}/clusters/{cluster}/snapshots/{snapshot}``.
+
+ This corresponds to the ``name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.cloud.bigtable_admin_v2.types.Snapshot:
+ A snapshot of a table at a particular
+ time. A snapshot can be used as a
+ checkpoint for data restoration or a
+ data source for a new table.
+
+ Note: This is a private alpha release of
+ Cloud Bigtable snapshots. This feature
+ is not currently available to most Cloud
+ Bigtable customers. This feature might
+ be changed in backward-incompatible ways
+ and is not recommended for production
+ use. It is not subject to any SLA or
+ deprecation policy.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.GetSnapshotRequest):
+ request = bigtable_table_admin.GetSnapshotRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.get_snapshot]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
+ # Send the request.
+ response = rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def list_snapshots(
+ self,
+ request: Optional[
+ Union[bigtable_table_admin.ListSnapshotsRequest, dict]
+ ] = None,
+ *,
+ parent: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> pagers.ListSnapshotsPager:
+ r"""Lists all snapshots associated with the specified
+ cluster.
+ Note: This is a private alpha release of Cloud Bigtable
+ snapshots. This feature is not currently available to
+ most Cloud Bigtable customers. This feature might be
+ changed in backward-incompatible ways and is not
+ recommended for production use. It is not subject to any
+ SLA or deprecation policy.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_list_snapshots():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.ListSnapshotsRequest(
+ parent="parent_value",
+ )
+
+ # Make the request
+ page_result = client.list_snapshots(request=request)
+
+ # Handle the response
+ for response in page_result:
+ print(response)
+
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.types.ListSnapshotsRequest, dict]):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots][google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots]
+
+ Note: This is a private alpha release of Cloud Bigtable
+ snapshots. This feature is not currently available to
+ most Cloud Bigtable customers. This feature might be
+ changed in backward-incompatible ways and is not
+ recommended for production use. It is not subject to any
+ SLA or deprecation policy.
+ parent (str):
+ Required. The unique name of the cluster for which
+ snapshots should be listed. Values are of the form
+ ``projects/{project}/instances/{instance}/clusters/{cluster}``.
+ Use ``{cluster} = '-'`` to list snapshots for all
+ clusters in an instance, e.g.,
+ ``projects/{project}/instances/{instance}/clusters/-``.
+
+ This corresponds to the ``parent`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.cloud.bigtable_admin_v2.services.bigtable_table_admin.pagers.ListSnapshotsPager:
+ Response message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots][google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots]
+
+ Note: This is a private alpha release of Cloud
+ Bigtable snapshots. This feature is not currently
+ available to most Cloud Bigtable customers. This
+ feature might be changed in backward-incompatible
+ ways and is not recommended for production use. It is
+ not subject to any SLA or deprecation policy.
+
+ Iterating over this object will yield results and
+ resolve additional pages automatically.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.ListSnapshotsRequest):
+ request = bigtable_table_admin.ListSnapshotsRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if parent is not None:
+ request.parent = parent
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.list_snapshots]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
+ # Send the request.
+ response = rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # This method is paged; wrap the response in a pager, which provides
+ # an `__iter__` convenience method.
+ response = pagers.ListSnapshotsPager(
+ method=rpc,
+ request=request,
+ response=response,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def delete_snapshot(
+ self,
+ request: Optional[
+ Union[bigtable_table_admin.DeleteSnapshotRequest, dict]
+ ] = None,
+ *,
+ name: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> None:
+ r"""Permanently deletes the specified snapshot.
+
+ Note: This is a private alpha release of Cloud Bigtable
+ snapshots. This feature is not currently available to
+ most Cloud Bigtable customers. This feature might be
+ changed in backward-incompatible ways and is not
+ recommended for production use. It is not subject to any
+ SLA or deprecation policy.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_delete_snapshot():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.DeleteSnapshotRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ client.delete_snapshot(request=request)
+
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.types.DeleteSnapshotRequest, dict]):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.DeleteSnapshot][google.bigtable.admin.v2.BigtableTableAdmin.DeleteSnapshot]
+
+ Note: This is a private alpha release of Cloud Bigtable
+ snapshots. This feature is not currently available to
+ most Cloud Bigtable customers. This feature might be
+ changed in backward-incompatible ways and is not
+ recommended for production use. It is not subject to any
+ SLA or deprecation policy.
+ name (str):
+ Required. The unique name of the snapshot to be deleted.
Values are of the form
``projects/{project}/instances/{instance}/clusters/{cluster}/snapshots/{snapshot}``.
- This corresponds to the ``name`` field
+ This corresponds to the ``name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.DeleteSnapshotRequest):
+ request = bigtable_table_admin.DeleteSnapshotRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.delete_snapshot]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
+ # Send the request.
+ rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ def create_backup(
+ self,
+ request: Optional[Union[bigtable_table_admin.CreateBackupRequest, dict]] = None,
+ *,
+ parent: Optional[str] = None,
+ backup_id: Optional[str] = None,
+ backup: Optional[table.Backup] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operation.Operation:
+ r"""Starts creating a new Cloud Bigtable Backup. The returned backup
+ [long-running operation][google.longrunning.Operation] can be
+ used to track creation of the backup. The
+ [metadata][google.longrunning.Operation.metadata] field type is
+ [CreateBackupMetadata][google.bigtable.admin.v2.CreateBackupMetadata].
+ The [response][google.longrunning.Operation.response] field type
+ is [Backup][google.bigtable.admin.v2.Backup], if successful.
+ Cancelling the returned operation will stop the creation and
+ delete the backup.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_create_backup():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ backup = bigtable_admin_v2.Backup()
+ backup.source_table = "source_table_value"
+
+ request = bigtable_admin_v2.CreateBackupRequest(
+ parent="parent_value",
+ backup_id="backup_id_value",
+ backup=backup,
+ )
+
+ # Make the request
+ operation = client.create_backup(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = operation.result()
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.types.CreateBackupRequest, dict]):
+ The request object. The request for
+ [CreateBackup][google.bigtable.admin.v2.BigtableTableAdmin.CreateBackup].
+ parent (str):
+ Required. This must be one of the clusters in the
+ instance in which this table is located. The backup will
+ be stored in this cluster. Values are of the form
+ ``projects/{project}/instances/{instance}/clusters/{cluster}``.
+
+ This corresponds to the ``parent`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ backup_id (str):
+ Required. The id of the backup to be created. The
+ ``backup_id`` along with the parent ``parent`` are
+ combined as {parent}/backups/{backup_id} to create the
+ full backup name, of the form:
+ ``projects/{project}/instances/{instance}/clusters/{cluster}/backups/{backup_id}``.
+ This string must be between 1 and 50 characters in
+ length and match the regex [*a-zA-Z0-9][-*.a-zA-Z0-9]\*.
+
+ This corresponds to the ``backup_id`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ backup (google.cloud.bigtable_admin_v2.types.Backup):
+ Required. The backup to create.
+ This corresponds to the ``backup`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.api_core.operation.Operation:
+ An object representing a long-running operation.
+
+ The result type for the operation will be
+ :class:`google.cloud.bigtable_admin_v2.types.Backup` A
+ backup of a Cloud Bigtable table.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent, backup_id, backup]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.CreateBackupRequest):
+ request = bigtable_table_admin.CreateBackupRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if parent is not None:
+ request.parent = parent
+ if backup_id is not None:
+ request.backup_id = backup_id
+ if backup is not None:
+ request.backup = backup
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.create_backup]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
+ # Send the request.
+ response = rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Wrap the response in an operation future.
+ response = operation.from_gapic(
+ response,
+ self._transport.operations_client,
+ table.Backup,
+ metadata_type=bigtable_table_admin.CreateBackupMetadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def get_backup(
+ self,
+ request: Optional[Union[bigtable_table_admin.GetBackupRequest, dict]] = None,
+ *,
+ name: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> table.Backup:
+ r"""Gets metadata on a pending or completed Cloud
+ Bigtable Backup.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_get_backup():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.GetBackupRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ response = client.get_backup(request=request)
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.types.GetBackupRequest, dict]):
+ The request object. The request for
+ [GetBackup][google.bigtable.admin.v2.BigtableTableAdmin.GetBackup].
+ name (str):
+ Required. Name of the backup. Values are of the form
+ ``projects/{project}/instances/{instance}/clusters/{cluster}/backups/{backup}``.
+
+ This corresponds to the ``name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.cloud.bigtable_admin_v2.types.Backup:
+ A backup of a Cloud Bigtable table.
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.GetBackupRequest):
+ request = bigtable_table_admin.GetBackupRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.get_backup]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
+ # Send the request.
+ response = rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def update_backup(
+ self,
+ request: Optional[Union[bigtable_table_admin.UpdateBackupRequest, dict]] = None,
+ *,
+ backup: Optional[table.Backup] = None,
+ update_mask: Optional[field_mask_pb2.FieldMask] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> table.Backup:
+ r"""Updates a pending or completed Cloud Bigtable Backup.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_update_backup():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ backup = bigtable_admin_v2.Backup()
+ backup.source_table = "source_table_value"
+
+ request = bigtable_admin_v2.UpdateBackupRequest(
+ backup=backup,
+ )
+
+ # Make the request
+ response = client.update_backup(request=request)
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.types.UpdateBackupRequest, dict]):
+ The request object. The request for
+ [UpdateBackup][google.bigtable.admin.v2.BigtableTableAdmin.UpdateBackup].
+ backup (google.cloud.bigtable_admin_v2.types.Backup):
+ Required. The backup to update. ``backup.name``, and the
+ fields to be updated as specified by ``update_mask`` are
+ required. Other fields are ignored. Update is only
+ supported for the following fields:
+
+ - ``backup.expire_time``.
+
+ This corresponds to the ``backup`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ update_mask (google.protobuf.field_mask_pb2.FieldMask):
+ Required. A mask specifying which fields (e.g.
+ ``expire_time``) in the Backup resource should be
+ updated. This mask is relative to the Backup resource,
+ not to the request message. The field mask must always
+ be specified; this prevents any future fields from being
+ erased accidentally by clients that do not know about
+ them.
+
+ This corresponds to the ``update_mask`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.cloud.bigtable_admin_v2.types.Backup:
+ A backup of a Cloud Bigtable table.
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [backup, update_mask]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.UpdateBackupRequest):
+ request = bigtable_table_admin.UpdateBackupRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if backup is not None:
+ request.backup = backup
+ if update_mask is not None:
+ request.update_mask = update_mask
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.update_backup]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata(
+ (("backup.name", request.backup.name),)
+ ),
+ )
+
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
+ # Send the request.
+ response = rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def delete_backup(
+ self,
+ request: Optional[Union[bigtable_table_admin.DeleteBackupRequest, dict]] = None,
+ *,
+ name: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> None:
+ r"""Deletes a pending or completed Cloud Bigtable backup.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_delete_backup():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.DeleteBackupRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ client.delete_backup(request=request)
+
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.types.DeleteBackupRequest, dict]):
+ The request object. The request for
+ [DeleteBackup][google.bigtable.admin.v2.BigtableTableAdmin.DeleteBackup].
+ name (str):
+ Required. Name of the backup to delete. Values are of
+ the form
+ ``projects/{project}/instances/{instance}/clusters/{cluster}/backups/{backup}``.
+
+ This corresponds to the ``name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.DeleteBackupRequest):
+ request = bigtable_table_admin.DeleteBackupRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if name is not None:
+ request.name = name
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.delete_backup]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ )
+
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
+ # Send the request.
+ rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ def list_backups(
+ self,
+ request: Optional[Union[bigtable_table_admin.ListBackupsRequest, dict]] = None,
+ *,
+ parent: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> pagers.ListBackupsPager:
+ r"""Lists Cloud Bigtable backups. Returns both completed
+ and pending backups.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_list_backups():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.ListBackupsRequest(
+ parent="parent_value",
+ )
+
+ # Make the request
+ page_result = client.list_backups(request=request)
+
+ # Handle the response
+ for response in page_result:
+ print(response)
+
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.types.ListBackupsRequest, dict]):
+ The request object. The request for
+ [ListBackups][google.bigtable.admin.v2.BigtableTableAdmin.ListBackups].
+ parent (str):
+ Required. The cluster to list backups from. Values are
+ of the form
+ ``projects/{project}/instances/{instance}/clusters/{cluster}``.
+ Use ``{cluster} = '-'`` to list backups for all clusters
+ in an instance, e.g.,
+ ``projects/{project}/instances/{instance}/clusters/-``.
+
+ This corresponds to the ``parent`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.cloud.bigtable_admin_v2.services.bigtable_table_admin.pagers.ListBackupsPager:
+ The response for
+ [ListBackups][google.bigtable.admin.v2.BigtableTableAdmin.ListBackups].
+
+ Iterating over this object will yield results and
+ resolve additional pages automatically.
+
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_table_admin.DeleteSnapshotRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
- if not isinstance(request, bigtable_table_admin.DeleteSnapshotRequest):
- request = bigtable_table_admin.DeleteSnapshotRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.ListBackupsRequest):
+ request = bigtable_table_admin.ListBackupsRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
- if name is not None:
- request.name = name
+ if parent is not None:
+ request.parent = parent
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = self._transport._wrapped_methods[self._transport.delete_snapshot]
+ rpc = self._transport._wrapped_methods[self._transport.list_backups]
# Certain fields should be provided within the metadata header;
# add these here.
metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
- rpc(
+ response = rpc(
request,
retry=retry,
timeout=timeout,
metadata=metadata,
)
- def create_backup(
+ # This method is paged; wrap the response in a pager, which provides
+ # an `__iter__` convenience method.
+ response = pagers.ListBackupsPager(
+ method=rpc,
+ request=request,
+ response=response,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def _restore_table(
self,
- request: Union[bigtable_table_admin.CreateBackupRequest, dict] = None,
+ request: Optional[Union[bigtable_table_admin.RestoreTableRequest, dict]] = None,
*,
- parent: str = None,
- backup_id: str = None,
- backup: table.Backup = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> operation.Operation:
- r"""Starts creating a new Cloud Bigtable Backup. The returned backup
- [long-running operation][google.longrunning.Operation] can be
- used to track creation of the backup. The
+ r"""Create a new table by restoring from a completed backup. The
+ returned table [long-running
+ operation][google.longrunning.Operation] can be used to track
+ the progress of the operation, and to cancel it. The
[metadata][google.longrunning.Operation.metadata] field type is
- [CreateBackupMetadata][google.bigtable.admin.v2.CreateBackupMetadata].
- The [response][google.longrunning.Operation.response] field type
- is [Backup][google.bigtable.admin.v2.Backup], if successful.
- Cancelling the returned operation will stop the creation and
- delete the backup.
+ [RestoreTableMetadata][google.bigtable.admin.v2.RestoreTableMetadata].
+ The [response][google.longrunning.Operation.response] type is
+ [Table][google.bigtable.admin.v2.Table], if successful.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_restore_table():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.RestoreTableRequest(
+ backup="backup_value",
+ parent="parent_value",
+ table_id="table_id_value",
+ )
+
+ # Make the request
+ operation = client._restore_table(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = operation.result()
+
+ # Handle the response
+ print(response)
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.CreateBackupRequest, dict]):
+ request (Union[google.cloud.bigtable_admin_v2.types.RestoreTableRequest, dict]):
The request object. The request for
- [CreateBackup][google.bigtable.admin.v2.BigtableTableAdmin.CreateBackup].
+ [RestoreTable][google.bigtable.admin.v2.BigtableTableAdmin.RestoreTable].
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.api_core.operation.Operation:
+ An object representing a long-running operation.
+
+ The result type for the operation will be :class:`google.cloud.bigtable_admin_v2.types.Table` A collection of user data indexed by row, column, and timestamp.
+ Each table is served using the resources of its
+ parent cluster.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.RestoreTableRequest):
+ request = bigtable_table_admin.RestoreTableRequest(request)
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.restore_table]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
+ # Send the request.
+ response = rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Wrap the response in an operation future.
+ response = operation.from_gapic(
+ response,
+ self._transport.operations_client,
+ table.Table,
+ metadata_type=bigtable_table_admin.RestoreTableMetadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def copy_backup(
+ self,
+ request: Optional[Union[bigtable_table_admin.CopyBackupRequest, dict]] = None,
+ *,
+ parent: Optional[str] = None,
+ backup_id: Optional[str] = None,
+ source_backup: Optional[str] = None,
+ expire_time: Optional[timestamp_pb2.Timestamp] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operation.Operation:
+ r"""Copy a Cloud Bigtable backup to a new backup in the
+ destination cluster located in the destination instance
+ and project.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_copy_backup():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.CopyBackupRequest(
+ parent="parent_value",
+ backup_id="backup_id_value",
+ source_backup="source_backup_value",
+ )
+
+ # Make the request
+ operation = client.copy_backup(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = operation.result()
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.types.CopyBackupRequest, dict]):
+ The request object. The request for
+ [CopyBackup][google.bigtable.admin.v2.BigtableTableAdmin.CopyBackup].
parent (str):
- Required. This must be one of the clusters in the
- instance in which this table is located. The backup will
- be stored in this cluster. Values are of the form
+ Required. The name of the destination cluster that will
+ contain the backup copy. The cluster must already exist.
+ Values are of the form:
``projects/{project}/instances/{instance}/clusters/{cluster}``.
This corresponds to the ``parent`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
backup_id (str):
- Required. The id of the backup to be created. The
- ``backup_id`` along with the parent ``parent`` are
- combined as {parent}/backups/{backup_id} to create the
- full backup name, of the form:
+ Required. The id of the new backup. The ``backup_id``
+ along with ``parent`` are combined as
+ {parent}/backups/{backup_id} to create the full backup
+ name, of the form:
``projects/{project}/instances/{instance}/clusters/{cluster}/backups/{backup_id}``.
This string must be between 1 and 50 characters in
- length and match the regex [*a-zA-Z0-9][-*.a-zA-Z0-9]*.
+ length and match the regex [*a-zA-Z0-9][-*.a-zA-Z0-9]\*.
This corresponds to the ``backup_id`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- backup (google.cloud.bigtable_admin_v2.types.Backup):
- Required. The backup to create.
- This corresponds to the ``backup`` field
+ source_backup (str):
+ Required. The source backup to be copied from. The
+ source backup needs to be in READY state for it to be
+ copied. Copying a copied backup is not allowed. Once
+ CopyBackup is in progress, the source backup cannot be
+ deleted or cleaned up on expiration until CopyBackup is
+ finished. Values are of the form:
+ ``projects//instances//clusters//backups/``.
+
+ This corresponds to the ``source_backup`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ expire_time (google.protobuf.timestamp_pb2.Timestamp):
+ Required. Required. The expiration time of the copied
+ backup with microsecond granularity that must be at
+ least 6 hours and at most 30 days from the time the
+ request is received. Once the ``expire_time`` has
+ passed, Cloud Bigtable will delete the backup and free
+ the resources used by the backup.
+
+ This corresponds to the ``expire_time`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.api_core.operation.Operation:
@@ -1845,40 +4336,195 @@ def create_backup(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([parent, backup_id, backup])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent, backup_id, source_backup, expire_time]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.CopyBackupRequest):
+ request = bigtable_table_admin.CopyBackupRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if parent is not None:
+ request.parent = parent
+ if backup_id is not None:
+ request.backup_id = backup_id
+ if source_backup is not None:
+ request.source_backup = source_backup
+ if expire_time is not None:
+ request.expire_time = expire_time
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.copy_backup]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ )
+
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
+ # Send the request.
+ response = rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Wrap the response in an operation future.
+ response = operation.from_gapic(
+ response,
+ self._transport.operations_client,
+ table.Backup,
+ metadata_type=bigtable_table_admin.CopyBackupMetadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def get_iam_policy(
+ self,
+ request: Optional[Union[iam_policy_pb2.GetIamPolicyRequest, dict]] = None,
+ *,
+ resource: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> policy_pb2.Policy:
+ r"""Gets the access control policy for a Bigtable
+ resource. Returns an empty policy if the resource exists
+ but does not have a policy set.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+ from google.iam.v1 import iam_policy_pb2 # type: ignore
+
+ def sample_get_iam_policy():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = iam_policy_pb2.GetIamPolicyRequest(
+ resource="resource_value",
+ )
+
+ # Make the request
+ response = client.get_iam_policy(request=request)
+
+ # Handle the response
+ print(response)
+
+ Args:
+ request (Union[google.iam.v1.iam_policy_pb2.GetIamPolicyRequest, dict]):
+ The request object. Request message for ``GetIamPolicy`` method.
+ resource (str):
+ REQUIRED: The resource for which the
+ policy is being requested. See the
+ operation documentation for the
+ appropriate value for this field.
+
+ This corresponds to the ``resource`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.iam.v1.policy_pb2.Policy:
+ An Identity and Access Management (IAM) policy, which specifies access
+ controls for Google Cloud resources.
+
+ A Policy is a collection of bindings. A binding binds
+ one or more members, or principals, to a single role.
+ Principals can be user accounts, service accounts,
+ Google groups, and domains (such as G Suite). A role
+ is a named list of permissions; each role can be an
+ IAM predefined role or a user-created custom role.
+
+ For some types of Google Cloud resources, a binding
+ can also specify a condition, which is a logical
+ expression that allows access to a resource only if
+ the expression evaluates to true. A condition can add
+ constraints based on attributes of the request, the
+ resource, or both. To learn which resources support
+ conditions in their IAM policies, see the [IAM
+ documentation](https://cloud.google.com/iam/help/conditions/resource-policies).
+
+ **JSON example:**
+
+ :literal:`` { "bindings": [ { "role": "roles/resourcemanager.organizationAdmin", "members": [ "user:mike@example.com", "group:admins@example.com", "domain:google.com", "serviceAccount:my-project-id@appspot.gserviceaccount.com" ] }, { "role": "roles/resourcemanager.organizationViewer", "members": [ "user:eve@example.com" ], "condition": { "title": "expirable access", "description": "Does not grant access after Sep 2020", "expression": "request.time < timestamp('2020-10-01T00:00:00.000Z')", } } ], "etag": "BwWWja0YfJA=", "version": 3 }`\ \`
+
+ **YAML example:**
+
+ :literal:`` bindings: - members: - user:mike@example.com - group:admins@example.com - domain:google.com - serviceAccount:my-project-id@appspot.gserviceaccount.com role: roles/resourcemanager.organizationAdmin - members: - user:eve@example.com role: roles/resourcemanager.organizationViewer condition: title: expirable access description: Does not grant access after Sep 2020 expression: request.time < timestamp('2020-10-01T00:00:00.000Z') etag: BwWWja0YfJA= version: 3`\ \`
+
+ For a description of IAM and its features, see the
+ [IAM
+ documentation](https://cloud.google.com/iam/docs/).
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [resource]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_table_admin.CreateBackupRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
- if not isinstance(request, bigtable_table_admin.CreateBackupRequest):
- request = bigtable_table_admin.CreateBackupRequest(request)
- # If we have keyword arguments corresponding to fields on the
- # request, apply these.
- if parent is not None:
- request.parent = parent
- if backup_id is not None:
- request.backup_id = backup_id
- if backup is not None:
- request.backup = backup
+ if isinstance(request, dict):
+ # - The request isn't a proto-plus wrapped type,
+ # so it must be constructed via keyword expansion.
+ request = iam_policy_pb2.GetIamPolicyRequest(**request)
+ elif not request:
+ # Null request, just make one.
+ request = iam_policy_pb2.GetIamPolicyRequest()
+ if resource is not None:
+ request.resource = resource
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = self._transport._wrapped_methods[self._transport.create_backup]
+ rpc = self._transport._wrapped_methods[self._transport.get_iam_policy]
# Certain fields should be provided within the metadata header;
# add these here.
metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ gapic_v1.routing_header.to_grpc_metadata((("resource", request.resource),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -1887,81 +4533,138 @@ def create_backup(
metadata=metadata,
)
- # Wrap the response in an operation future.
- response = operation.from_gapic(
- response,
- self._transport.operations_client,
- table.Backup,
- metadata_type=bigtable_table_admin.CreateBackupMetadata,
- )
-
# Done; return the response.
return response
- def get_backup(
+ def set_iam_policy(
self,
- request: Union[bigtable_table_admin.GetBackupRequest, dict] = None,
+ request: Optional[Union[iam_policy_pb2.SetIamPolicyRequest, dict]] = None,
*,
- name: str = None,
+ resource: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
- ) -> table.Backup:
- r"""Gets metadata on a pending or completed Cloud
- Bigtable Backup.
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> policy_pb2.Policy:
+ r"""Sets the access control policy on a Bigtable
+ resource. Replaces any existing policy.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+ from google.iam.v1 import iam_policy_pb2 # type: ignore
+
+ def sample_set_iam_policy():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = iam_policy_pb2.SetIamPolicyRequest(
+ resource="resource_value",
+ )
+
+ # Make the request
+ response = client.set_iam_policy(request=request)
+
+ # Handle the response
+ print(response)
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.GetBackupRequest, dict]):
- The request object. The request for
- [GetBackup][google.bigtable.admin.v2.BigtableTableAdmin.GetBackup].
- name (str):
- Required. Name of the backup. Values are of the form
- ``projects/{project}/instances/{instance}/clusters/{cluster}/backups/{backup}``.
+ request (Union[google.iam.v1.iam_policy_pb2.SetIamPolicyRequest, dict]):
+ The request object. Request message for ``SetIamPolicy`` method.
+ resource (str):
+ REQUIRED: The resource for which the
+ policy is being specified. See the
+ operation documentation for the
+ appropriate value for this field.
- This corresponds to the ``name`` field
+ This corresponds to the ``resource`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
- google.cloud.bigtable_admin_v2.types.Backup:
- A backup of a Cloud Bigtable table.
+ google.iam.v1.policy_pb2.Policy:
+ An Identity and Access Management (IAM) policy, which specifies access
+ controls for Google Cloud resources.
+
+ A Policy is a collection of bindings. A binding binds
+ one or more members, or principals, to a single role.
+ Principals can be user accounts, service accounts,
+ Google groups, and domains (such as G Suite). A role
+ is a named list of permissions; each role can be an
+ IAM predefined role or a user-created custom role.
+
+ For some types of Google Cloud resources, a binding
+ can also specify a condition, which is a logical
+ expression that allows access to a resource only if
+ the expression evaluates to true. A condition can add
+ constraints based on attributes of the request, the
+ resource, or both. To learn which resources support
+ conditions in their IAM policies, see the [IAM
+ documentation](https://cloud.google.com/iam/help/conditions/resource-policies).
+
+ **JSON example:**
+
+ :literal:`` { "bindings": [ { "role": "roles/resourcemanager.organizationAdmin", "members": [ "user:mike@example.com", "group:admins@example.com", "domain:google.com", "serviceAccount:my-project-id@appspot.gserviceaccount.com" ] }, { "role": "roles/resourcemanager.organizationViewer", "members": [ "user:eve@example.com" ], "condition": { "title": "expirable access", "description": "Does not grant access after Sep 2020", "expression": "request.time < timestamp('2020-10-01T00:00:00.000Z')", } } ], "etag": "BwWWja0YfJA=", "version": 3 }`\ \`
+
+ **YAML example:**
+
+ :literal:`` bindings: - members: - user:mike@example.com - group:admins@example.com - domain:google.com - serviceAccount:my-project-id@appspot.gserviceaccount.com role: roles/resourcemanager.organizationAdmin - members: - user:eve@example.com role: roles/resourcemanager.organizationViewer condition: title: expirable access description: Does not grant access after Sep 2020 expression: request.time < timestamp('2020-10-01T00:00:00.000Z') etag: BwWWja0YfJA= version: 3`\ \`
+
+ For a description of IAM and its features, see the
+ [IAM
+ documentation](https://cloud.google.com/iam/docs/).
+
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [resource]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_table_admin.GetBackupRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
- if not isinstance(request, bigtable_table_admin.GetBackupRequest):
- request = bigtable_table_admin.GetBackupRequest(request)
- # If we have keyword arguments corresponding to fields on the
- # request, apply these.
- if name is not None:
- request.name = name
+ if isinstance(request, dict):
+ # - The request isn't a proto-plus wrapped type,
+ # so it must be constructed via keyword expansion.
+ request = iam_policy_pb2.SetIamPolicyRequest(**request)
+ elif not request:
+ # Null request, just make one.
+ request = iam_policy_pb2.SetIamPolicyRequest()
+ if resource is not None:
+ request.resource = resource
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = self._transport._wrapped_methods[self._transport.get_backup]
+ rpc = self._transport._wrapped_methods[self._transport.set_iam_policy]
# Certain fields should be provided within the metadata header;
# add these here.
metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
+ gapic_v1.routing_header.to_grpc_metadata((("resource", request.resource),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -1973,90 +4676,118 @@ def get_backup(
# Done; return the response.
return response
- def update_backup(
+ def test_iam_permissions(
self,
- request: Union[bigtable_table_admin.UpdateBackupRequest, dict] = None,
+ request: Optional[Union[iam_policy_pb2.TestIamPermissionsRequest, dict]] = None,
*,
- backup: table.Backup = None,
- update_mask: field_mask_pb2.FieldMask = None,
+ resource: Optional[str] = None,
+ permissions: Optional[MutableSequence[str]] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
- ) -> table.Backup:
- r"""Updates a pending or completed Cloud Bigtable Backup.
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> iam_policy_pb2.TestIamPermissionsResponse:
+ r"""Returns permissions that the caller has on the
+ specified Bigtable resource.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+ from google.iam.v1 import iam_policy_pb2 # type: ignore
+
+ def sample_test_iam_permissions():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = iam_policy_pb2.TestIamPermissionsRequest(
+ resource="resource_value",
+ permissions=['permissions_value1', 'permissions_value2'],
+ )
- Args:
- request (Union[google.cloud.bigtable_admin_v2.types.UpdateBackupRequest, dict]):
- The request object. The request for
- [UpdateBackup][google.bigtable.admin.v2.BigtableTableAdmin.UpdateBackup].
- backup (google.cloud.bigtable_admin_v2.types.Backup):
- Required. The backup to update. ``backup.name``, and the
- fields to be updated as specified by ``update_mask`` are
- required. Other fields are ignored. Update is only
- supported for the following fields:
+ # Make the request
+ response = client.test_iam_permissions(request=request)
- - ``backup.expire_time``.
+ # Handle the response
+ print(response)
- This corresponds to the ``backup`` field
+ Args:
+ request (Union[google.iam.v1.iam_policy_pb2.TestIamPermissionsRequest, dict]):
+ The request object. Request message for ``TestIamPermissions`` method.
+ resource (str):
+ REQUIRED: The resource for which the
+ policy detail is being requested. See
+ the operation documentation for the
+ appropriate value for this field.
+
+ This corresponds to the ``resource`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- update_mask (google.protobuf.field_mask_pb2.FieldMask):
- Required. A mask specifying which fields (e.g.
- ``expire_time``) in the Backup resource should be
- updated. This mask is relative to the Backup resource,
- not to the request message. The field mask must always
- be specified; this prevents any future fields from being
- erased accidentally by clients that do not know about
- them.
+ permissions (MutableSequence[str]):
+ The set of permissions to check for the ``resource``.
+ Permissions with wildcards (such as '*' or 'storage.*')
+ are not allowed. For more information see `IAM
+ Overview `__.
- This corresponds to the ``update_mask`` field
+ This corresponds to the ``permissions`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
- google.cloud.bigtable_admin_v2.types.Backup:
- A backup of a Cloud Bigtable table.
+ google.iam.v1.iam_policy_pb2.TestIamPermissionsResponse:
+ Response message for TestIamPermissions method.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([backup, update_mask])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [resource, permissions]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_table_admin.UpdateBackupRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
- if not isinstance(request, bigtable_table_admin.UpdateBackupRequest):
- request = bigtable_table_admin.UpdateBackupRequest(request)
- # If we have keyword arguments corresponding to fields on the
- # request, apply these.
- if backup is not None:
- request.backup = backup
- if update_mask is not None:
- request.update_mask = update_mask
+ if isinstance(request, dict):
+ # - The request isn't a proto-plus wrapped type,
+ # so it must be constructed via keyword expansion.
+ request = iam_policy_pb2.TestIamPermissionsRequest(**request)
+ elif not request:
+ # Null request, just make one.
+ request = iam_policy_pb2.TestIamPermissionsRequest()
+ if resource is not None:
+ request.resource = resource
+ if permissions:
+ request.permissions.extend(permissions)
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = self._transport._wrapped_methods[self._transport.update_backup]
+ rpc = self._transport._wrapped_methods[self._transport.test_iam_permissions]
# Certain fields should be provided within the metadata header;
# add these here.
metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata(
- (("backup.name", request.backup.name),)
- ),
+ gapic_v1.routing_header.to_grpc_metadata((("resource", request.resource),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -2068,140 +4799,130 @@ def update_backup(
# Done; return the response.
return response
- def delete_backup(
+ def create_schema_bundle(
self,
- request: Union[bigtable_table_admin.DeleteBackupRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_table_admin.CreateSchemaBundleRequest, dict]
+ ] = None,
*,
- name: str = None,
+ parent: Optional[str] = None,
+ schema_bundle_id: Optional[str] = None,
+ schema_bundle: Optional[table.SchemaBundle] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
- ) -> None:
- r"""Deletes a pending or completed Cloud Bigtable backup.
-
- Args:
- request (Union[google.cloud.bigtable_admin_v2.types.DeleteBackupRequest, dict]):
- The request object. The request for
- [DeleteBackup][google.bigtable.admin.v2.BigtableTableAdmin.DeleteBackup].
- name (str):
- Required. Name of the backup to delete. Values are of
- the form
- ``projects/{project}/instances/{instance}/clusters/{cluster}/backups/{backup}``.
-
- This corresponds to the ``name`` field
- on the ``request`` instance; if ``request`` is provided, this
- should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
- should be retried.
- timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
- """
- # Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name])
- if request is not None and has_flattened_params:
- raise ValueError(
- "If the `request` argument is set, then none of "
- "the individual field arguments should be set."
- )
-
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_table_admin.DeleteBackupRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
- if not isinstance(request, bigtable_table_admin.DeleteBackupRequest):
- request = bigtable_table_admin.DeleteBackupRequest(request)
- # If we have keyword arguments corresponding to fields on the
- # request, apply these.
- if name is not None:
- request.name = name
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operation.Operation:
+ r"""Creates a new schema bundle in the specified table.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_create_schema_bundle():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ schema_bundle = bigtable_admin_v2.SchemaBundle()
+ schema_bundle.proto_schema.proto_descriptors = b'proto_descriptors_blob'
+
+ request = bigtable_admin_v2.CreateSchemaBundleRequest(
+ parent="parent_value",
+ schema_bundle_id="schema_bundle_id_value",
+ schema_bundle=schema_bundle,
+ )
- # Wrap the RPC method; this adds retry and timeout information,
- # and friendly error handling.
- rpc = self._transport._wrapped_methods[self._transport.delete_backup]
+ # Make the request
+ operation = client.create_schema_bundle(request=request)
- # Certain fields should be provided within the metadata header;
- # add these here.
- metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
- )
+ print("Waiting for operation to complete...")
- # Send the request.
- rpc(
- request,
- retry=retry,
- timeout=timeout,
- metadata=metadata,
- )
+ response = operation.result()
- def list_backups(
- self,
- request: Union[bigtable_table_admin.ListBackupsRequest, dict] = None,
- *,
- parent: str = None,
- retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
- ) -> pagers.ListBackupsPager:
- r"""Lists Cloud Bigtable backups. Returns both completed
- and pending backups.
+ # Handle the response
+ print(response)
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.ListBackupsRequest, dict]):
+ request (Union[google.cloud.bigtable_admin_v2.types.CreateSchemaBundleRequest, dict]):
The request object. The request for
- [ListBackups][google.bigtable.admin.v2.BigtableTableAdmin.ListBackups].
+ [CreateSchemaBundle][google.bigtable.admin.v2.BigtableTableAdmin.CreateSchemaBundle].
parent (str):
- Required. The cluster to list backups from. Values are
- of the form
- ``projects/{project}/instances/{instance}/clusters/{cluster}``.
- Use ``{cluster} = '-'`` to list backups for all clusters
- in an instance, e.g.,
- ``projects/{project}/instances/{instance}/clusters/-``.
+ Required. The parent resource where this schema bundle
+ will be created. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}``.
This corresponds to the ``parent`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
+ schema_bundle_id (str):
+ Required. The unique ID to use for
+ the schema bundle, which will become the
+ final component of the schema bundle's
+ resource name.
+
+ This corresponds to the ``schema_bundle_id`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ schema_bundle (google.cloud.bigtable_admin_v2.types.SchemaBundle):
+ Required. The schema bundle to
+ create.
+
+ This corresponds to the ``schema_bundle`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
- google.cloud.bigtable_admin_v2.services.bigtable_table_admin.pagers.ListBackupsPager:
- The response for
- [ListBackups][google.bigtable.admin.v2.BigtableTableAdmin.ListBackups].
+ google.api_core.operation.Operation:
+ An object representing a long-running operation.
- Iterating over this object will yield results and
- resolve additional pages automatically.
+ The result type for the operation will be
+ :class:`google.cloud.bigtable_admin_v2.types.SchemaBundle`
+ A named collection of related schemas.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([parent])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent, schema_bundle_id, schema_bundle]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_table_admin.ListBackupsRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
- if not isinstance(request, bigtable_table_admin.ListBackupsRequest):
- request = bigtable_table_admin.ListBackupsRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.CreateSchemaBundleRequest):
+ request = bigtable_table_admin.CreateSchemaBundleRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
if parent is not None:
request.parent = parent
+ if schema_bundle_id is not None:
+ request.schema_bundle_id = schema_bundle_id
+ if schema_bundle is not None:
+ request.schema_bundle = schema_bundle
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = self._transport._wrapped_methods[self._transport.list_backups]
+ rpc = self._transport._wrapped_methods[self._transport.create_schema_bundle]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -2209,6 +4930,9 @@ def list_backups(
gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -2217,73 +4941,141 @@ def list_backups(
metadata=metadata,
)
- # This method is paged; wrap the response in a pager, which provides
- # an `__iter__` convenience method.
- response = pagers.ListBackupsPager(
- method=rpc,
- request=request,
- response=response,
- metadata=metadata,
+ # Wrap the response in an operation future.
+ response = operation.from_gapic(
+ response,
+ self._transport.operations_client,
+ table.SchemaBundle,
+ metadata_type=bigtable_table_admin.CreateSchemaBundleMetadata,
)
# Done; return the response.
return response
- def restore_table(
+ def update_schema_bundle(
self,
- request: Union[bigtable_table_admin.RestoreTableRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_table_admin.UpdateSchemaBundleRequest, dict]
+ ] = None,
*,
+ schema_bundle: Optional[table.SchemaBundle] = None,
+ update_mask: Optional[field_mask_pb2.FieldMask] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> operation.Operation:
- r"""Create a new table by restoring from a completed backup. The new
- table must be in the same project as the instance containing the
- backup. The returned table [long-running
- operation][google.longrunning.Operation] can be used to track
- the progress of the operation, and to cancel it. The
- [metadata][google.longrunning.Operation.metadata] field type is
- [RestoreTableMetadata][google.bigtable.admin.RestoreTableMetadata].
- The [response][google.longrunning.Operation.response] type is
- [Table][google.bigtable.admin.v2.Table], if successful.
+ r"""Updates a schema bundle in the specified table.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_update_schema_bundle():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ schema_bundle = bigtable_admin_v2.SchemaBundle()
+ schema_bundle.proto_schema.proto_descriptors = b'proto_descriptors_blob'
+
+ request = bigtable_admin_v2.UpdateSchemaBundleRequest(
+ schema_bundle=schema_bundle,
+ )
+
+ # Make the request
+ operation = client.update_schema_bundle(request=request)
+
+ print("Waiting for operation to complete...")
+
+ response = operation.result()
+
+ # Handle the response
+ print(response)
Args:
- request (Union[google.cloud.bigtable_admin_v2.types.RestoreTableRequest, dict]):
+ request (Union[google.cloud.bigtable_admin_v2.types.UpdateSchemaBundleRequest, dict]):
The request object. The request for
- [RestoreTable][google.bigtable.admin.v2.BigtableTableAdmin.RestoreTable].
+ [UpdateSchemaBundle][google.bigtable.admin.v2.BigtableTableAdmin.UpdateSchemaBundle].
+ schema_bundle (google.cloud.bigtable_admin_v2.types.SchemaBundle):
+ Required. The schema bundle to update.
+
+ The schema bundle's ``name`` field is used to identify
+ the schema bundle to update. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}/schemaBundles/{schema_bundle}``
+
+ This corresponds to the ``schema_bundle`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ update_mask (google.protobuf.field_mask_pb2.FieldMask):
+ Optional. The list of fields to
+ update.
+
+ This corresponds to the ``update_mask`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.api_core.operation.Operation:
An object representing a long-running operation.
- The result type for the operation will be :class:`google.cloud.bigtable_admin_v2.types.Table` A collection of user data indexed by row, column, and timestamp.
- Each table is served using the resources of its
- parent cluster.
+ The result type for the operation will be
+ :class:`google.cloud.bigtable_admin_v2.types.SchemaBundle`
+ A named collection of related schemas.
"""
# Create or coerce a protobuf request object.
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable_table_admin.RestoreTableRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
- if not isinstance(request, bigtable_table_admin.RestoreTableRequest):
- request = bigtable_table_admin.RestoreTableRequest(request)
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [schema_bundle, update_mask]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.UpdateSchemaBundleRequest):
+ request = bigtable_table_admin.UpdateSchemaBundleRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if schema_bundle is not None:
+ request.schema_bundle = schema_bundle
+ if update_mask is not None:
+ request.update_mask = update_mask
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = self._transport._wrapped_methods[self._transport.restore_table]
+ rpc = self._transport._wrapped_methods[self._transport.update_schema_bundle]
# Certain fields should be provided within the metadata header;
# add these here.
metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
+ gapic_v1.routing_header.to_grpc_metadata(
+ (("schema_bundle.name", request.schema_bundle.name),)
+ ),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -2296,140 +5088,114 @@ def restore_table(
response = operation.from_gapic(
response,
self._transport.operations_client,
- table.Table,
- metadata_type=bigtable_table_admin.RestoreTableMetadata,
+ table.SchemaBundle,
+ metadata_type=bigtable_table_admin.UpdateSchemaBundleMetadata,
)
# Done; return the response.
return response
- def get_iam_policy(
+ def get_schema_bundle(
self,
- request: Union[iam_policy_pb2.GetIamPolicyRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_table_admin.GetSchemaBundleRequest, dict]
+ ] = None,
*,
- resource: str = None,
+ name: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
- ) -> policy_pb2.Policy:
- r"""Gets the access control policy for a Table or Backup
- resource. Returns an empty policy if the resource exists
- but does not have a policy set.
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> table.SchemaBundle:
+ r"""Gets metadata information about the specified schema
+ bundle.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_get_schema_bundle():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.GetSchemaBundleRequest(
+ name="name_value",
+ )
+
+ # Make the request
+ response = client.get_schema_bundle(request=request)
+
+ # Handle the response
+ print(response)
Args:
- request (Union[google.iam.v1.iam_policy_pb2.GetIamPolicyRequest, dict]):
- The request object. Request message for `GetIamPolicy`
- method.
- resource (str):
- REQUIRED: The resource for which the
- policy is being requested. See the
- operation documentation for the
- appropriate value for this field.
+ request (Union[google.cloud.bigtable_admin_v2.types.GetSchemaBundleRequest, dict]):
+ The request object. The request for
+ [GetSchemaBundle][google.bigtable.admin.v2.BigtableTableAdmin.GetSchemaBundle].
+ name (str):
+ Required. The unique name of the schema bundle to
+ retrieve. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}/schemaBundles/{schema_bundle}``
- This corresponds to the ``resource`` field
+ This corresponds to the ``name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
- google.iam.v1.policy_pb2.Policy:
- An Identity and Access Management (IAM) policy, which specifies access
- controls for Google Cloud resources.
-
- A Policy is a collection of bindings. A binding binds
- one or more members, or principals, to a single role.
- Principals can be user accounts, service accounts,
- Google groups, and domains (such as G Suite). A role
- is a named list of permissions; each role can be an
- IAM predefined role or a user-created custom role.
-
- For some types of Google Cloud resources, a binding
- can also specify a condition, which is a logical
- expression that allows access to a resource only if
- the expression evaluates to true. A condition can add
- constraints based on attributes of the request, the
- resource, or both. To learn which resources support
- conditions in their IAM policies, see the [IAM
- documentation](\ https://cloud.google.com/iam/help/conditions/resource-policies).
-
- **JSON example:**
-
- {
- "bindings": [
- {
- "role":
- "roles/resourcemanager.organizationAdmin",
- "members": [ "user:mike@example.com",
- "group:admins@example.com",
- "domain:google.com",
- "serviceAccount:my-project-id@appspot.gserviceaccount.com"
- ]
-
- }, { "role":
- "roles/resourcemanager.organizationViewer",
- "members": [ "user:eve@example.com" ],
- "condition": { "title": "expirable access",
- "description": "Does not grant access after
- Sep 2020", "expression": "request.time <
- timestamp('2020-10-01T00:00:00.000Z')", } }
-
- ], "etag": "BwWWja0YfJA=", "version": 3
-
- }
-
- **YAML example:**
-
- bindings: - members: - user:\ mike@example.com -
- group:\ admins@example.com - domain:google.com -
- serviceAccount:\ my-project-id@appspot.gserviceaccount.com
- role: roles/resourcemanager.organizationAdmin -
- members: - user:\ eve@example.com role:
- roles/resourcemanager.organizationViewer
- condition: title: expirable access description:
- Does not grant access after Sep 2020 expression:
- request.time <
- timestamp('2020-10-01T00:00:00.000Z') etag:
- BwWWja0YfJA= version: 3
-
- For a description of IAM and its features, see the
- [IAM
- documentation](\ https://cloud.google.com/iam/docs/).
+ google.cloud.bigtable_admin_v2.types.SchemaBundle:
+ A named collection of related
+ schemas.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([resource])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- if isinstance(request, dict):
- # The request isn't a proto-plus wrapped type,
- # so it must be constructed via keyword expansion.
- request = iam_policy_pb2.GetIamPolicyRequest(**request)
- elif not request:
- # Null request, just make one.
- request = iam_policy_pb2.GetIamPolicyRequest()
- if resource is not None:
- request.resource = resource
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.GetSchemaBundleRequest):
+ request = bigtable_table_admin.GetSchemaBundleRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if name is not None:
+ request.name = name
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = self._transport._wrapped_methods[self._transport.get_iam_policy]
+ rpc = self._transport._wrapped_methods[self._transport.get_schema_bundle]
# Certain fields should be provided within the metadata header;
# add these here.
metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata((("resource", request.resource),)),
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -2441,132 +5207,111 @@ def get_iam_policy(
# Done; return the response.
return response
- def set_iam_policy(
+ def list_schema_bundles(
self,
- request: Union[iam_policy_pb2.SetIamPolicyRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_table_admin.ListSchemaBundlesRequest, dict]
+ ] = None,
*,
- resource: str = None,
+ parent: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
- ) -> policy_pb2.Policy:
- r"""Sets the access control policy on a Table or Backup
- resource. Replaces any existing policy.
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> pagers.ListSchemaBundlesPager:
+ r"""Lists all schema bundles associated with the
+ specified table.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_list_schema_bundles():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.ListSchemaBundlesRequest(
+ parent="parent_value",
+ )
+
+ # Make the request
+ page_result = client.list_schema_bundles(request=request)
+
+ # Handle the response
+ for response in page_result:
+ print(response)
Args:
- request (Union[google.iam.v1.iam_policy_pb2.SetIamPolicyRequest, dict]):
- The request object. Request message for `SetIamPolicy`
- method.
- resource (str):
- REQUIRED: The resource for which the
- policy is being specified. See the
- operation documentation for the
- appropriate value for this field.
+ request (Union[google.cloud.bigtable_admin_v2.types.ListSchemaBundlesRequest, dict]):
+ The request object. The request for
+ [ListSchemaBundles][google.bigtable.admin.v2.BigtableTableAdmin.ListSchemaBundles].
+ parent (str):
+ Required. The parent, which owns this collection of
+ schema bundles. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}``.
- This corresponds to the ``resource`` field
+ This corresponds to the ``parent`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
- google.iam.v1.policy_pb2.Policy:
- An Identity and Access Management (IAM) policy, which specifies access
- controls for Google Cloud resources.
-
- A Policy is a collection of bindings. A binding binds
- one or more members, or principals, to a single role.
- Principals can be user accounts, service accounts,
- Google groups, and domains (such as G Suite). A role
- is a named list of permissions; each role can be an
- IAM predefined role or a user-created custom role.
-
- For some types of Google Cloud resources, a binding
- can also specify a condition, which is a logical
- expression that allows access to a resource only if
- the expression evaluates to true. A condition can add
- constraints based on attributes of the request, the
- resource, or both. To learn which resources support
- conditions in their IAM policies, see the [IAM
- documentation](\ https://cloud.google.com/iam/help/conditions/resource-policies).
-
- **JSON example:**
-
- {
- "bindings": [
- {
- "role":
- "roles/resourcemanager.organizationAdmin",
- "members": [ "user:mike@example.com",
- "group:admins@example.com",
- "domain:google.com",
- "serviceAccount:my-project-id@appspot.gserviceaccount.com"
- ]
-
- }, { "role":
- "roles/resourcemanager.organizationViewer",
- "members": [ "user:eve@example.com" ],
- "condition": { "title": "expirable access",
- "description": "Does not grant access after
- Sep 2020", "expression": "request.time <
- timestamp('2020-10-01T00:00:00.000Z')", } }
-
- ], "etag": "BwWWja0YfJA=", "version": 3
-
- }
-
- **YAML example:**
-
- bindings: - members: - user:\ mike@example.com -
- group:\ admins@example.com - domain:google.com -
- serviceAccount:\ my-project-id@appspot.gserviceaccount.com
- role: roles/resourcemanager.organizationAdmin -
- members: - user:\ eve@example.com role:
- roles/resourcemanager.organizationViewer
- condition: title: expirable access description:
- Does not grant access after Sep 2020 expression:
- request.time <
- timestamp('2020-10-01T00:00:00.000Z') etag:
- BwWWja0YfJA= version: 3
+ google.cloud.bigtable_admin_v2.services.bigtable_table_admin.pagers.ListSchemaBundlesPager:
+ The response for
+ [ListSchemaBundles][google.bigtable.admin.v2.BigtableTableAdmin.ListSchemaBundles].
- For a description of IAM and its features, see the
- [IAM
- documentation](\ https://cloud.google.com/iam/docs/).
+ Iterating over this object will yield results and
+ resolve additional pages automatically.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([resource])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [parent]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- if isinstance(request, dict):
- # The request isn't a proto-plus wrapped type,
- # so it must be constructed via keyword expansion.
- request = iam_policy_pb2.SetIamPolicyRequest(**request)
- elif not request:
- # Null request, just make one.
- request = iam_policy_pb2.SetIamPolicyRequest()
- if resource is not None:
- request.resource = resource
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.ListSchemaBundlesRequest):
+ request = bigtable_table_admin.ListSchemaBundlesRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if parent is not None:
+ request.parent = parent
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = self._transport._wrapped_methods[self._transport.set_iam_policy]
+ rpc = self._transport._wrapped_methods[self._transport.list_schema_bundles]
# Certain fields should be provided within the metadata header;
# add these here.
metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata((("resource", request.resource),)),
+ gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -2575,98 +5320,120 @@ def set_iam_policy(
metadata=metadata,
)
+ # This method is paged; wrap the response in a pager, which provides
+ # an `__iter__` convenience method.
+ response = pagers.ListSchemaBundlesPager(
+ method=rpc,
+ request=request,
+ response=response,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
# Done; return the response.
return response
- def test_iam_permissions(
+ def delete_schema_bundle(
self,
- request: Union[iam_policy_pb2.TestIamPermissionsRequest, dict] = None,
+ request: Optional[
+ Union[bigtable_table_admin.DeleteSchemaBundleRequest, dict]
+ ] = None,
*,
- resource: str = None,
- permissions: Sequence[str] = None,
+ name: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
- ) -> iam_policy_pb2.TestIamPermissionsResponse:
- r"""Returns permissions that the caller has on the
- specified Table or Backup resource.
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> None:
+ r"""Deletes a schema bundle in the specified table.
+
+ .. code-block:: python
+
+ # This snippet has been automatically generated and should be regarded as a
+ # code template only.
+ # It will require modifications to work:
+ # - It may require correct/in-range values for request initialization.
+ # - It may require specifying regional endpoints when creating the service
+ # client as shown in:
+ # https://googleapis.dev/python/google-api-core/latest/client_options.html
+ from google.cloud import bigtable_admin_v2
+
+ def sample_delete_schema_bundle():
+ # Create a client
+ client = bigtable_admin_v2.BigtableTableAdminClient()
+
+ # Initialize request argument(s)
+ request = bigtable_admin_v2.DeleteSchemaBundleRequest(
+ name="name_value",
+ )
- Args:
- request (Union[google.iam.v1.iam_policy_pb2.TestIamPermissionsRequest, dict]):
- The request object. Request message for
- `TestIamPermissions` method.
- resource (str):
- REQUIRED: The resource for which the
- policy detail is being requested. See
- the operation documentation for the
- appropriate value for this field.
+ # Make the request
+ client.delete_schema_bundle(request=request)
- This corresponds to the ``resource`` field
- on the ``request`` instance; if ``request`` is provided, this
- should not be set.
- permissions (Sequence[str]):
- The set of permissions to check for the ``resource``.
- Permissions with wildcards (such as '*' or 'storage.*')
- are not allowed. For more information see `IAM
- Overview `__.
+ Args:
+ request (Union[google.cloud.bigtable_admin_v2.types.DeleteSchemaBundleRequest, dict]):
+ The request object. The request for
+ [DeleteSchemaBundle][google.bigtable.admin.v2.BigtableTableAdmin.DeleteSchemaBundle].
+ name (str):
+ Required. The unique name of the schema bundle to
+ delete. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}/schemaBundles/{schema_bundle}``
- This corresponds to the ``permissions`` field
+ This corresponds to the ``name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
-
- Returns:
- google.iam.v1.iam_policy_pb2.TestIamPermissionsResponse:
- Response message for TestIamPermissions method.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([resource, permissions])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- if isinstance(request, dict):
- # The request isn't a proto-plus wrapped type,
- # so it must be constructed via keyword expansion.
- request = iam_policy_pb2.TestIamPermissionsRequest(**request)
- elif not request:
- # Null request, just make one.
- request = iam_policy_pb2.TestIamPermissionsRequest()
- if resource is not None:
- request.resource = resource
- if permissions:
- request.permissions.extend(permissions)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable_table_admin.DeleteSchemaBundleRequest):
+ request = bigtable_table_admin.DeleteSchemaBundleRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if name is not None:
+ request.name = name
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = self._transport._wrapped_methods[self._transport.test_iam_permissions]
+ rpc = self._transport._wrapped_methods[self._transport.delete_schema_bundle]
# Certain fields should be provided within the metadata header;
# add these here.
metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata((("resource", request.resource),)),
+ gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
- response = rpc(
+ rpc(
request,
retry=retry,
timeout=timeout,
metadata=metadata,
)
- # Done; return the response.
- return response
-
- def __enter__(self):
+ def __enter__(self) -> "BaseBigtableTableAdminClient":
return self
def __exit__(self, type, value, traceback):
@@ -2680,14 +5447,11 @@ def __exit__(self, type, value, traceback):
self.transport.close()
-try:
- DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
- gapic_version=pkg_resources.get_distribution(
- "google-cloud-bigtable-admin",
- ).version,
- )
-except pkg_resources.DistributionNotFound:
- DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
+DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
+ gapic_version=package_version.__version__
+)
+if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER
+ DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__
-__all__ = ("BigtableTableAdminClient",)
+__all__ = ("BaseBigtableTableAdminClient",)
diff --git a/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/pagers.py b/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/pagers.py
index e639227df..e6d83ba63 100644
--- a/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/pagers.py
+++ b/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/pagers.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -13,6 +13,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+from google.api_core import gapic_v1
+from google.api_core import retry as retries
+from google.api_core import retry_async as retries_async
from typing import (
Any,
AsyncIterator,
@@ -22,8 +25,18 @@
Tuple,
Optional,
Iterator,
+ Union,
)
+try:
+ OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None]
+ OptionalAsyncRetry = Union[
+ retries_async.AsyncRetry, gapic_v1.method._MethodDefault, None
+ ]
+except AttributeError: # pragma: NO COVER
+ OptionalRetry = Union[retries.Retry, object, None] # type: ignore
+ OptionalAsyncRetry = Union[retries_async.AsyncRetry, object, None] # type: ignore
+
from google.cloud.bigtable_admin_v2.types import bigtable_table_admin
from google.cloud.bigtable_admin_v2.types import table
@@ -52,7 +65,9 @@ def __init__(
request: bigtable_table_admin.ListTablesRequest,
response: bigtable_table_admin.ListTablesResponse,
*,
- metadata: Sequence[Tuple[str, str]] = ()
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
):
"""Instantiate the pager.
@@ -63,12 +78,19 @@ def __init__(
The initial request object.
response (google.cloud.bigtable_admin_v2.types.ListTablesResponse):
The initial response object.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ retry (google.api_core.retry.Retry): Designation of what errors,
+ if any, should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
"""
self._method = method
self._request = bigtable_table_admin.ListTablesRequest(request)
self._response = response
+ self._retry = retry
+ self._timeout = timeout
self._metadata = metadata
def __getattr__(self, name: str) -> Any:
@@ -79,7 +101,12 @@ def pages(self) -> Iterator[bigtable_table_admin.ListTablesResponse]:
yield self._response
while self._response.next_page_token:
self._request.page_token = self._response.next_page_token
- self._response = self._method(self._request, metadata=self._metadata)
+ self._response = self._method(
+ self._request,
+ retry=self._retry,
+ timeout=self._timeout,
+ metadata=self._metadata,
+ )
yield self._response
def __iter__(self) -> Iterator[table.Table]:
@@ -114,7 +141,9 @@ def __init__(
request: bigtable_table_admin.ListTablesRequest,
response: bigtable_table_admin.ListTablesResponse,
*,
- metadata: Sequence[Tuple[str, str]] = ()
+ retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
):
"""Instantiates the pager.
@@ -125,12 +154,19 @@ def __init__(
The initial request object.
response (google.cloud.bigtable_admin_v2.types.ListTablesResponse):
The initial response object.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ retry (google.api_core.retry.AsyncRetry): Designation of what errors,
+ if any, should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
"""
self._method = method
self._request = bigtable_table_admin.ListTablesRequest(request)
self._response = response
+ self._retry = retry
+ self._timeout = timeout
self._metadata = metadata
def __getattr__(self, name: str) -> Any:
@@ -141,7 +177,12 @@ async def pages(self) -> AsyncIterator[bigtable_table_admin.ListTablesResponse]:
yield self._response
while self._response.next_page_token:
self._request.page_token = self._response.next_page_token
- self._response = await self._method(self._request, metadata=self._metadata)
+ self._response = await self._method(
+ self._request,
+ retry=self._retry,
+ timeout=self._timeout,
+ metadata=self._metadata,
+ )
yield self._response
def __aiter__(self) -> AsyncIterator[table.Table]:
@@ -156,6 +197,166 @@ def __repr__(self) -> str:
return "{0}<{1!r}>".format(self.__class__.__name__, self._response)
+class ListAuthorizedViewsPager:
+ """A pager for iterating through ``list_authorized_views`` requests.
+
+ This class thinly wraps an initial
+ :class:`google.cloud.bigtable_admin_v2.types.ListAuthorizedViewsResponse` object, and
+ provides an ``__iter__`` method to iterate through its
+ ``authorized_views`` field.
+
+ If there are more pages, the ``__iter__`` method will make additional
+ ``ListAuthorizedViews`` requests and continue to iterate
+ through the ``authorized_views`` field on the
+ corresponding responses.
+
+ All the usual :class:`google.cloud.bigtable_admin_v2.types.ListAuthorizedViewsResponse`
+ attributes are available on the pager. If multiple requests are made, only
+ the most recent response is retained, and thus used for attribute lookup.
+ """
+
+ def __init__(
+ self,
+ method: Callable[..., bigtable_table_admin.ListAuthorizedViewsResponse],
+ request: bigtable_table_admin.ListAuthorizedViewsRequest,
+ response: bigtable_table_admin.ListAuthorizedViewsResponse,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
+ ):
+ """Instantiate the pager.
+
+ Args:
+ method (Callable): The method that was originally called, and
+ which instantiated this pager.
+ request (google.cloud.bigtable_admin_v2.types.ListAuthorizedViewsRequest):
+ The initial request object.
+ response (google.cloud.bigtable_admin_v2.types.ListAuthorizedViewsResponse):
+ The initial response object.
+ retry (google.api_core.retry.Retry): Designation of what errors,
+ if any, should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+ """
+ self._method = method
+ self._request = bigtable_table_admin.ListAuthorizedViewsRequest(request)
+ self._response = response
+ self._retry = retry
+ self._timeout = timeout
+ self._metadata = metadata
+
+ def __getattr__(self, name: str) -> Any:
+ return getattr(self._response, name)
+
+ @property
+ def pages(self) -> Iterator[bigtable_table_admin.ListAuthorizedViewsResponse]:
+ yield self._response
+ while self._response.next_page_token:
+ self._request.page_token = self._response.next_page_token
+ self._response = self._method(
+ self._request,
+ retry=self._retry,
+ timeout=self._timeout,
+ metadata=self._metadata,
+ )
+ yield self._response
+
+ def __iter__(self) -> Iterator[table.AuthorizedView]:
+ for page in self.pages:
+ yield from page.authorized_views
+
+ def __repr__(self) -> str:
+ return "{0}<{1!r}>".format(self.__class__.__name__, self._response)
+
+
+class ListAuthorizedViewsAsyncPager:
+ """A pager for iterating through ``list_authorized_views`` requests.
+
+ This class thinly wraps an initial
+ :class:`google.cloud.bigtable_admin_v2.types.ListAuthorizedViewsResponse` object, and
+ provides an ``__aiter__`` method to iterate through its
+ ``authorized_views`` field.
+
+ If there are more pages, the ``__aiter__`` method will make additional
+ ``ListAuthorizedViews`` requests and continue to iterate
+ through the ``authorized_views`` field on the
+ corresponding responses.
+
+ All the usual :class:`google.cloud.bigtable_admin_v2.types.ListAuthorizedViewsResponse`
+ attributes are available on the pager. If multiple requests are made, only
+ the most recent response is retained, and thus used for attribute lookup.
+ """
+
+ def __init__(
+ self,
+ method: Callable[
+ ..., Awaitable[bigtable_table_admin.ListAuthorizedViewsResponse]
+ ],
+ request: bigtable_table_admin.ListAuthorizedViewsRequest,
+ response: bigtable_table_admin.ListAuthorizedViewsResponse,
+ *,
+ retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
+ ):
+ """Instantiates the pager.
+
+ Args:
+ method (Callable): The method that was originally called, and
+ which instantiated this pager.
+ request (google.cloud.bigtable_admin_v2.types.ListAuthorizedViewsRequest):
+ The initial request object.
+ response (google.cloud.bigtable_admin_v2.types.ListAuthorizedViewsResponse):
+ The initial response object.
+ retry (google.api_core.retry.AsyncRetry): Designation of what errors,
+ if any, should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+ """
+ self._method = method
+ self._request = bigtable_table_admin.ListAuthorizedViewsRequest(request)
+ self._response = response
+ self._retry = retry
+ self._timeout = timeout
+ self._metadata = metadata
+
+ def __getattr__(self, name: str) -> Any:
+ return getattr(self._response, name)
+
+ @property
+ async def pages(
+ self,
+ ) -> AsyncIterator[bigtable_table_admin.ListAuthorizedViewsResponse]:
+ yield self._response
+ while self._response.next_page_token:
+ self._request.page_token = self._response.next_page_token
+ self._response = await self._method(
+ self._request,
+ retry=self._retry,
+ timeout=self._timeout,
+ metadata=self._metadata,
+ )
+ yield self._response
+
+ def __aiter__(self) -> AsyncIterator[table.AuthorizedView]:
+ async def async_generator():
+ async for page in self.pages:
+ for response in page.authorized_views:
+ yield response
+
+ return async_generator()
+
+ def __repr__(self) -> str:
+ return "{0}<{1!r}>".format(self.__class__.__name__, self._response)
+
+
class ListSnapshotsPager:
"""A pager for iterating through ``list_snapshots`` requests.
@@ -180,7 +381,9 @@ def __init__(
request: bigtable_table_admin.ListSnapshotsRequest,
response: bigtable_table_admin.ListSnapshotsResponse,
*,
- metadata: Sequence[Tuple[str, str]] = ()
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
):
"""Instantiate the pager.
@@ -191,12 +394,19 @@ def __init__(
The initial request object.
response (google.cloud.bigtable_admin_v2.types.ListSnapshotsResponse):
The initial response object.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ retry (google.api_core.retry.Retry): Designation of what errors,
+ if any, should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
"""
self._method = method
self._request = bigtable_table_admin.ListSnapshotsRequest(request)
self._response = response
+ self._retry = retry
+ self._timeout = timeout
self._metadata = metadata
def __getattr__(self, name: str) -> Any:
@@ -207,7 +417,12 @@ def pages(self) -> Iterator[bigtable_table_admin.ListSnapshotsResponse]:
yield self._response
while self._response.next_page_token:
self._request.page_token = self._response.next_page_token
- self._response = self._method(self._request, metadata=self._metadata)
+ self._response = self._method(
+ self._request,
+ retry=self._retry,
+ timeout=self._timeout,
+ metadata=self._metadata,
+ )
yield self._response
def __iter__(self) -> Iterator[table.Snapshot]:
@@ -242,7 +457,9 @@ def __init__(
request: bigtable_table_admin.ListSnapshotsRequest,
response: bigtable_table_admin.ListSnapshotsResponse,
*,
- metadata: Sequence[Tuple[str, str]] = ()
+ retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
):
"""Instantiates the pager.
@@ -253,12 +470,19 @@ def __init__(
The initial request object.
response (google.cloud.bigtable_admin_v2.types.ListSnapshotsResponse):
The initial response object.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ retry (google.api_core.retry.AsyncRetry): Designation of what errors,
+ if any, should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
"""
self._method = method
self._request = bigtable_table_admin.ListSnapshotsRequest(request)
self._response = response
+ self._retry = retry
+ self._timeout = timeout
self._metadata = metadata
def __getattr__(self, name: str) -> Any:
@@ -269,7 +493,12 @@ async def pages(self) -> AsyncIterator[bigtable_table_admin.ListSnapshotsRespons
yield self._response
while self._response.next_page_token:
self._request.page_token = self._response.next_page_token
- self._response = await self._method(self._request, metadata=self._metadata)
+ self._response = await self._method(
+ self._request,
+ retry=self._retry,
+ timeout=self._timeout,
+ metadata=self._metadata,
+ )
yield self._response
def __aiter__(self) -> AsyncIterator[table.Snapshot]:
@@ -308,7 +537,9 @@ def __init__(
request: bigtable_table_admin.ListBackupsRequest,
response: bigtable_table_admin.ListBackupsResponse,
*,
- metadata: Sequence[Tuple[str, str]] = ()
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
):
"""Instantiate the pager.
@@ -319,12 +550,19 @@ def __init__(
The initial request object.
response (google.cloud.bigtable_admin_v2.types.ListBackupsResponse):
The initial response object.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ retry (google.api_core.retry.Retry): Designation of what errors,
+ if any, should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
"""
self._method = method
self._request = bigtable_table_admin.ListBackupsRequest(request)
self._response = response
+ self._retry = retry
+ self._timeout = timeout
self._metadata = metadata
def __getattr__(self, name: str) -> Any:
@@ -335,7 +573,12 @@ def pages(self) -> Iterator[bigtable_table_admin.ListBackupsResponse]:
yield self._response
while self._response.next_page_token:
self._request.page_token = self._response.next_page_token
- self._response = self._method(self._request, metadata=self._metadata)
+ self._response = self._method(
+ self._request,
+ retry=self._retry,
+ timeout=self._timeout,
+ metadata=self._metadata,
+ )
yield self._response
def __iter__(self) -> Iterator[table.Backup]:
@@ -370,7 +613,9 @@ def __init__(
request: bigtable_table_admin.ListBackupsRequest,
response: bigtable_table_admin.ListBackupsResponse,
*,
- metadata: Sequence[Tuple[str, str]] = ()
+ retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
):
"""Instantiates the pager.
@@ -381,12 +626,19 @@ def __init__(
The initial request object.
response (google.cloud.bigtable_admin_v2.types.ListBackupsResponse):
The initial response object.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ retry (google.api_core.retry.AsyncRetry): Designation of what errors,
+ if any, should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
"""
self._method = method
self._request = bigtable_table_admin.ListBackupsRequest(request)
self._response = response
+ self._retry = retry
+ self._timeout = timeout
self._metadata = metadata
def __getattr__(self, name: str) -> Any:
@@ -397,7 +649,12 @@ async def pages(self) -> AsyncIterator[bigtable_table_admin.ListBackupsResponse]
yield self._response
while self._response.next_page_token:
self._request.page_token = self._response.next_page_token
- self._response = await self._method(self._request, metadata=self._metadata)
+ self._response = await self._method(
+ self._request,
+ retry=self._retry,
+ timeout=self._timeout,
+ metadata=self._metadata,
+ )
yield self._response
def __aiter__(self) -> AsyncIterator[table.Backup]:
@@ -410,3 +667,163 @@ async def async_generator():
def __repr__(self) -> str:
return "{0}<{1!r}>".format(self.__class__.__name__, self._response)
+
+
+class ListSchemaBundlesPager:
+ """A pager for iterating through ``list_schema_bundles`` requests.
+
+ This class thinly wraps an initial
+ :class:`google.cloud.bigtable_admin_v2.types.ListSchemaBundlesResponse` object, and
+ provides an ``__iter__`` method to iterate through its
+ ``schema_bundles`` field.
+
+ If there are more pages, the ``__iter__`` method will make additional
+ ``ListSchemaBundles`` requests and continue to iterate
+ through the ``schema_bundles`` field on the
+ corresponding responses.
+
+ All the usual :class:`google.cloud.bigtable_admin_v2.types.ListSchemaBundlesResponse`
+ attributes are available on the pager. If multiple requests are made, only
+ the most recent response is retained, and thus used for attribute lookup.
+ """
+
+ def __init__(
+ self,
+ method: Callable[..., bigtable_table_admin.ListSchemaBundlesResponse],
+ request: bigtable_table_admin.ListSchemaBundlesRequest,
+ response: bigtable_table_admin.ListSchemaBundlesResponse,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
+ ):
+ """Instantiate the pager.
+
+ Args:
+ method (Callable): The method that was originally called, and
+ which instantiated this pager.
+ request (google.cloud.bigtable_admin_v2.types.ListSchemaBundlesRequest):
+ The initial request object.
+ response (google.cloud.bigtable_admin_v2.types.ListSchemaBundlesResponse):
+ The initial response object.
+ retry (google.api_core.retry.Retry): Designation of what errors,
+ if any, should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+ """
+ self._method = method
+ self._request = bigtable_table_admin.ListSchemaBundlesRequest(request)
+ self._response = response
+ self._retry = retry
+ self._timeout = timeout
+ self._metadata = metadata
+
+ def __getattr__(self, name: str) -> Any:
+ return getattr(self._response, name)
+
+ @property
+ def pages(self) -> Iterator[bigtable_table_admin.ListSchemaBundlesResponse]:
+ yield self._response
+ while self._response.next_page_token:
+ self._request.page_token = self._response.next_page_token
+ self._response = self._method(
+ self._request,
+ retry=self._retry,
+ timeout=self._timeout,
+ metadata=self._metadata,
+ )
+ yield self._response
+
+ def __iter__(self) -> Iterator[table.SchemaBundle]:
+ for page in self.pages:
+ yield from page.schema_bundles
+
+ def __repr__(self) -> str:
+ return "{0}<{1!r}>".format(self.__class__.__name__, self._response)
+
+
+class ListSchemaBundlesAsyncPager:
+ """A pager for iterating through ``list_schema_bundles`` requests.
+
+ This class thinly wraps an initial
+ :class:`google.cloud.bigtable_admin_v2.types.ListSchemaBundlesResponse` object, and
+ provides an ``__aiter__`` method to iterate through its
+ ``schema_bundles`` field.
+
+ If there are more pages, the ``__aiter__`` method will make additional
+ ``ListSchemaBundles`` requests and continue to iterate
+ through the ``schema_bundles`` field on the
+ corresponding responses.
+
+ All the usual :class:`google.cloud.bigtable_admin_v2.types.ListSchemaBundlesResponse`
+ attributes are available on the pager. If multiple requests are made, only
+ the most recent response is retained, and thus used for attribute lookup.
+ """
+
+ def __init__(
+ self,
+ method: Callable[
+ ..., Awaitable[bigtable_table_admin.ListSchemaBundlesResponse]
+ ],
+ request: bigtable_table_admin.ListSchemaBundlesRequest,
+ response: bigtable_table_admin.ListSchemaBundlesResponse,
+ *,
+ retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
+ ):
+ """Instantiates the pager.
+
+ Args:
+ method (Callable): The method that was originally called, and
+ which instantiated this pager.
+ request (google.cloud.bigtable_admin_v2.types.ListSchemaBundlesRequest):
+ The initial request object.
+ response (google.cloud.bigtable_admin_v2.types.ListSchemaBundlesResponse):
+ The initial response object.
+ retry (google.api_core.retry.AsyncRetry): Designation of what errors,
+ if any, should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+ """
+ self._method = method
+ self._request = bigtable_table_admin.ListSchemaBundlesRequest(request)
+ self._response = response
+ self._retry = retry
+ self._timeout = timeout
+ self._metadata = metadata
+
+ def __getattr__(self, name: str) -> Any:
+ return getattr(self._response, name)
+
+ @property
+ async def pages(
+ self,
+ ) -> AsyncIterator[bigtable_table_admin.ListSchemaBundlesResponse]:
+ yield self._response
+ while self._response.next_page_token:
+ self._request.page_token = self._response.next_page_token
+ self._response = await self._method(
+ self._request,
+ retry=self._retry,
+ timeout=self._timeout,
+ metadata=self._metadata,
+ )
+ yield self._response
+
+ def __aiter__(self) -> AsyncIterator[table.SchemaBundle]:
+ async def async_generator():
+ async for page in self.pages:
+ for response in page.schema_bundles:
+ yield response
+
+ return async_generator()
+
+ def __repr__(self) -> str:
+ return "{0}<{1!r}>".format(self.__class__.__name__, self._response)
diff --git a/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/README.rst b/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/README.rst
new file mode 100644
index 000000000..0e8f40ec3
--- /dev/null
+++ b/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/README.rst
@@ -0,0 +1,9 @@
+
+transport inheritance structure
+_______________________________
+
+`BigtableTableAdminTransport` is the ABC for all transports.
+- public child `BigtableTableAdminGrpcTransport` for sync gRPC transport (defined in `grpc.py`).
+- public child `BigtableTableAdminGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`).
+- private child `_BaseBigtableTableAdminRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`).
+- public child `BigtableTableAdminRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`).
diff --git a/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/__init__.py b/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/__init__.py
index 78a7850e4..e7621f781 100644
--- a/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/__init__.py
+++ b/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/__init__.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -19,6 +19,8 @@
from .base import BigtableTableAdminTransport
from .grpc import BigtableTableAdminGrpcTransport
from .grpc_asyncio import BigtableTableAdminGrpcAsyncIOTransport
+from .rest import BigtableTableAdminRestTransport
+from .rest import BigtableTableAdminRestInterceptor
# Compile a registry of transports.
@@ -27,9 +29,12 @@
) # type: Dict[str, Type[BigtableTableAdminTransport]]
_transport_registry["grpc"] = BigtableTableAdminGrpcTransport
_transport_registry["grpc_asyncio"] = BigtableTableAdminGrpcAsyncIOTransport
+_transport_registry["rest"] = BigtableTableAdminRestTransport
__all__ = (
"BigtableTableAdminTransport",
"BigtableTableAdminGrpcTransport",
"BigtableTableAdminGrpcAsyncIOTransport",
+ "BigtableTableAdminRestTransport",
+ "BigtableTableAdminRestInterceptor",
)
diff --git a/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/base.py b/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/base.py
index 5370416a0..8ad08df3f 100644
--- a/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/base.py
+++ b/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/base.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -15,7 +15,8 @@
#
import abc
from typing import Awaitable, Callable, Dict, Optional, Sequence, Union
-import pkg_resources
+
+from google.cloud.bigtable_admin_v2 import gapic_version as package_version
import google.auth # type: ignore
import google.api_core
@@ -25,6 +26,7 @@
from google.api_core import operations_v1
from google.auth import credentials as ga_credentials # type: ignore
from google.oauth2 import service_account # type: ignore
+import google.protobuf
from google.cloud.bigtable_admin_v2.types import bigtable_table_admin
from google.cloud.bigtable_admin_v2.types import table
@@ -34,14 +36,12 @@
from google.longrunning import operations_pb2 # type: ignore
from google.protobuf import empty_pb2 # type: ignore
-try:
- DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
- gapic_version=pkg_resources.get_distribution(
- "google-cloud-bigtable-admin",
- ).version,
- )
-except pkg_resources.DistributionNotFound:
- DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
+DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
+ gapic_version=package_version.__version__
+)
+
+if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER
+ DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__
class BigtableTableAdminTransport(abc.ABC):
@@ -62,27 +62,29 @@ def __init__(
self,
*,
host: str = DEFAULT_HOST,
- credentials: ga_credentials.Credentials = None,
+ credentials: Optional[ga_credentials.Credentials] = None,
credentials_file: Optional[str] = None,
scopes: Optional[Sequence[str]] = None,
quota_project_id: Optional[str] = None,
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
always_use_jwt_access: Optional[bool] = False,
+ api_audience: Optional[str] = None,
**kwargs,
) -> None:
"""Instantiate the transport.
Args:
host (Optional[str]):
- The hostname to connect to.
+ The hostname to connect to (default: 'bigtableadmin.googleapis.com').
credentials (Optional[google.auth.credentials.Credentials]): The
authorization credentials to attach to requests. These
credentials identify the application to the service; if none
are specified, the client will attempt to ascertain the
credentials from the environment.
- credentials_file (Optional[str]): A file with credentials that can
+ credentials_file (Optional[str]): Deprecated. A file with credentials that can
be loaded with :func:`google.auth.load_credentials_from_file`.
- This argument is mutually exclusive with credentials.
+ This argument is mutually exclusive with credentials. This argument will be
+ removed in the next major version of this library.
scopes (Optional[Sequence[str]]): A list of scopes.
quota_project_id (Optional[str]): An optional project to use for billing
and quota.
@@ -95,15 +97,12 @@ def __init__(
be used for service account credentials.
"""
- # Save the hostname. Default to port 443 (HTTPS) if none is specified.
- if ":" not in host:
- host += ":443"
- self._host = host
-
scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES}
# Save the scopes.
self._scopes = scopes
+ if not hasattr(self, "_ignore_credentials"):
+ self._ignore_credentials: bool = False
# If no credentials are provided, then determine the appropriate
# defaults.
@@ -116,10 +115,15 @@ def __init__(
credentials, _ = google.auth.load_credentials_from_file(
credentials_file, **scopes_kwargs, quota_project_id=quota_project_id
)
- elif credentials is None:
+ elif credentials is None and not self._ignore_credentials:
credentials, _ = google.auth.default(
**scopes_kwargs, quota_project_id=quota_project_id
)
+ # Don't apply audience if the credentials file passed from user.
+ if hasattr(credentials, "with_gdch_audience"):
+ credentials = credentials.with_gdch_audience(
+ api_audience if api_audience else host
+ )
# If the credentials are service account credentials, then always try to use self signed JWT.
if (
@@ -132,6 +136,15 @@ def __init__(
# Save the credentials.
self._credentials = credentials
+ # Save the hostname. Default to port 443 (HTTPS) if none is specified.
+ if ":" not in host:
+ host += ":443"
+ self._host = host
+
+ @property
+ def host(self):
+ return self._host
+
def _prep_wrapped_messages(self, client_info):
# Precompute the wrapped methods.
self._wrapped_methods = {
@@ -175,9 +188,44 @@ def _prep_wrapped_messages(self, client_info):
default_timeout=60.0,
client_info=client_info,
),
+ self.update_table: gapic_v1.method.wrap_method(
+ self.update_table,
+ default_timeout=None,
+ client_info=client_info,
+ ),
self.delete_table: gapic_v1.method.wrap_method(
self.delete_table,
- default_timeout=60.0,
+ default_timeout=300.0,
+ client_info=client_info,
+ ),
+ self.undelete_table: gapic_v1.method.wrap_method(
+ self.undelete_table,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.create_authorized_view: gapic_v1.method.wrap_method(
+ self.create_authorized_view,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.list_authorized_views: gapic_v1.method.wrap_method(
+ self.list_authorized_views,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.get_authorized_view: gapic_v1.method.wrap_method(
+ self.get_authorized_view,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.update_authorized_view: gapic_v1.method.wrap_method(
+ self.update_authorized_view,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.delete_authorized_view: gapic_v1.method.wrap_method(
+ self.delete_authorized_view,
+ default_timeout=None,
client_info=client_info,
),
self.modify_column_families: gapic_v1.method.wrap_method(
@@ -215,9 +263,9 @@ def _prep_wrapped_messages(self, client_info):
core_exceptions.DeadlineExceeded,
core_exceptions.ServiceUnavailable,
),
- deadline=60.0,
+ deadline=3600.0,
),
- default_timeout=60.0,
+ default_timeout=3600.0,
client_info=client_info,
),
self.snapshot_table: gapic_v1.method.wrap_method(
@@ -257,7 +305,7 @@ def _prep_wrapped_messages(self, client_info):
),
self.delete_snapshot: gapic_v1.method.wrap_method(
self.delete_snapshot,
- default_timeout=60.0,
+ default_timeout=300.0,
client_info=client_info,
),
self.create_backup: gapic_v1.method.wrap_method(
@@ -287,7 +335,7 @@ def _prep_wrapped_messages(self, client_info):
),
self.delete_backup: gapic_v1.method.wrap_method(
self.delete_backup,
- default_timeout=60.0,
+ default_timeout=300.0,
client_info=client_info,
),
self.list_backups: gapic_v1.method.wrap_method(
@@ -310,6 +358,11 @@ def _prep_wrapped_messages(self, client_info):
default_timeout=60.0,
client_info=client_info,
),
+ self.copy_backup: gapic_v1.method.wrap_method(
+ self.copy_backup,
+ default_timeout=None,
+ client_info=client_info,
+ ),
self.get_iam_policy: gapic_v1.method.wrap_method(
self.get_iam_policy,
default_retry=retries.Retry(
@@ -345,6 +398,31 @@ def _prep_wrapped_messages(self, client_info):
default_timeout=60.0,
client_info=client_info,
),
+ self.create_schema_bundle: gapic_v1.method.wrap_method(
+ self.create_schema_bundle,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.update_schema_bundle: gapic_v1.method.wrap_method(
+ self.update_schema_bundle,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.get_schema_bundle: gapic_v1.method.wrap_method(
+ self.get_schema_bundle,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.list_schema_bundles: gapic_v1.method.wrap_method(
+ self.list_schema_bundles,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.delete_schema_bundle: gapic_v1.method.wrap_method(
+ self.delete_schema_bundle,
+ default_timeout=None,
+ client_info=client_info,
+ ),
}
def close(self):
@@ -400,6 +478,15 @@ def get_table(
]:
raise NotImplementedError()
+ @property
+ def update_table(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.UpdateTableRequest],
+ Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]],
+ ]:
+ raise NotImplementedError()
+
@property
def delete_table(
self,
@@ -409,6 +496,63 @@ def delete_table(
]:
raise NotImplementedError()
+ @property
+ def undelete_table(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.UndeleteTableRequest],
+ Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def create_authorized_view(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.CreateAuthorizedViewRequest],
+ Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def list_authorized_views(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.ListAuthorizedViewsRequest],
+ Union[
+ bigtable_table_admin.ListAuthorizedViewsResponse,
+ Awaitable[bigtable_table_admin.ListAuthorizedViewsResponse],
+ ],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def get_authorized_view(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.GetAuthorizedViewRequest],
+ Union[table.AuthorizedView, Awaitable[table.AuthorizedView]],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def update_authorized_view(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.UpdateAuthorizedViewRequest],
+ Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def delete_authorized_view(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.DeleteAuthorizedViewRequest],
+ Union[empty_pb2.Empty, Awaitable[empty_pb2.Empty]],
+ ]:
+ raise NotImplementedError()
+
@property
def modify_column_families(
self,
@@ -547,6 +691,15 @@ def restore_table(
]:
raise NotImplementedError()
+ @property
+ def copy_backup(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.CopyBackupRequest],
+ Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]],
+ ]:
+ raise NotImplementedError()
+
@property
def get_iam_policy(
self,
@@ -577,6 +730,54 @@ def test_iam_permissions(
]:
raise NotImplementedError()
+ @property
+ def create_schema_bundle(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.CreateSchemaBundleRequest],
+ Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def update_schema_bundle(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.UpdateSchemaBundleRequest],
+ Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def get_schema_bundle(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.GetSchemaBundleRequest],
+ Union[table.SchemaBundle, Awaitable[table.SchemaBundle]],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def list_schema_bundles(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.ListSchemaBundlesRequest],
+ Union[
+ bigtable_table_admin.ListSchemaBundlesResponse,
+ Awaitable[bigtable_table_admin.ListSchemaBundlesResponse],
+ ],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def delete_schema_bundle(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.DeleteSchemaBundleRequest],
+ Union[empty_pb2.Empty, Awaitable[empty_pb2.Empty]],
+ ]:
+ raise NotImplementedError()
+
@property
def kind(self) -> str:
raise NotImplementedError()
diff --git a/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/grpc.py b/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/grpc.py
index f6c2c478d..f8d1058c8 100644
--- a/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/grpc.py
+++ b/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/grpc.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -13,6 +13,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+import json
+import logging as std_logging
+import pickle
import warnings
from typing import Callable, Dict, Optional, Sequence, Tuple, Union
@@ -22,8 +25,11 @@
import google.auth # type: ignore
from google.auth import credentials as ga_credentials # type: ignore
from google.auth.transport.grpc import SslCredentials # type: ignore
+from google.protobuf.json_format import MessageToJson
+import google.protobuf.message
import grpc # type: ignore
+import proto # type: ignore
from google.cloud.bigtable_admin_v2.types import bigtable_table_admin
from google.cloud.bigtable_admin_v2.types import table
@@ -34,6 +40,80 @@
from google.protobuf import empty_pb2 # type: ignore
from .base import BigtableTableAdminTransport, DEFAULT_CLIENT_INFO
+try:
+ from google.api_core import client_logging # type: ignore
+
+ CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER
+except ImportError: # pragma: NO COVER
+ CLIENT_LOGGING_SUPPORTED = False
+
+_LOGGER = std_logging.getLogger(__name__)
+
+
+class _LoggingClientInterceptor(grpc.UnaryUnaryClientInterceptor): # pragma: NO COVER
+ def intercept_unary_unary(self, continuation, client_call_details, request):
+ logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ std_logging.DEBUG
+ )
+ if logging_enabled: # pragma: NO COVER
+ request_metadata = client_call_details.metadata
+ if isinstance(request, proto.Message):
+ request_payload = type(request).to_json(request)
+ elif isinstance(request, google.protobuf.message.Message):
+ request_payload = MessageToJson(request)
+ else:
+ request_payload = f"{type(request).__name__}: {pickle.dumps(request)}"
+
+ request_metadata = {
+ key: value.decode("utf-8") if isinstance(value, bytes) else value
+ for key, value in request_metadata
+ }
+ grpc_request = {
+ "payload": request_payload,
+ "requestMethod": "grpc",
+ "metadata": dict(request_metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for {client_call_details.method}",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": str(client_call_details.method),
+ "request": grpc_request,
+ "metadata": grpc_request["metadata"],
+ },
+ )
+ response = continuation(client_call_details, request)
+ if logging_enabled: # pragma: NO COVER
+ response_metadata = response.trailing_metadata()
+ # Convert gRPC metadata `` to list of tuples
+ metadata = (
+ dict([(k, str(v)) for k, v in response_metadata])
+ if response_metadata
+ else None
+ )
+ result = response.result()
+ if isinstance(result, proto.Message):
+ response_payload = type(result).to_json(result)
+ elif isinstance(result, google.protobuf.message.Message):
+ response_payload = MessageToJson(result)
+ else:
+ response_payload = f"{type(result).__name__}: {pickle.dumps(result)}"
+ grpc_response = {
+ "payload": response_payload,
+ "metadata": metadata,
+ "status": "OK",
+ }
+ _LOGGER.debug(
+ f"Received response for {client_call_details.method}.",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": client_call_details.method,
+ "response": grpc_response,
+ "metadata": grpc_response["metadata"],
+ },
+ )
+ return response
+
class BigtableTableAdminGrpcTransport(BigtableTableAdminTransport):
"""gRPC backend transport for BigtableTableAdmin.
@@ -58,36 +138,41 @@ def __init__(
self,
*,
host: str = "bigtableadmin.googleapis.com",
- credentials: ga_credentials.Credentials = None,
- credentials_file: str = None,
- scopes: Sequence[str] = None,
- channel: grpc.Channel = None,
- api_mtls_endpoint: str = None,
- client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
- ssl_channel_credentials: grpc.ChannelCredentials = None,
- client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None,
+ credentials: Optional[ga_credentials.Credentials] = None,
+ credentials_file: Optional[str] = None,
+ scopes: Optional[Sequence[str]] = None,
+ channel: Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]] = None,
+ api_mtls_endpoint: Optional[str] = None,
+ client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None,
+ ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None,
+ client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None,
quota_project_id: Optional[str] = None,
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
always_use_jwt_access: Optional[bool] = False,
+ api_audience: Optional[str] = None,
) -> None:
"""Instantiate the transport.
Args:
host (Optional[str]):
- The hostname to connect to.
+ The hostname to connect to (default: 'bigtableadmin.googleapis.com').
credentials (Optional[google.auth.credentials.Credentials]): The
authorization credentials to attach to requests. These
credentials identify the application to the service; if none
are specified, the client will attempt to ascertain the
credentials from the environment.
- This argument is ignored if ``channel`` is provided.
- credentials_file (Optional[str]): A file with credentials that can
+ This argument is ignored if a ``channel`` instance is provided.
+ credentials_file (Optional[str]): Deprecated. A file with credentials that can
be loaded with :func:`google.auth.load_credentials_from_file`.
- This argument is ignored if ``channel`` is provided.
+ This argument is ignored if a ``channel`` instance is provided.
+ This argument will be removed in the next major version of this library.
scopes (Optional(Sequence[str])): A list of scopes. This argument is
- ignored if ``channel`` is provided.
- channel (Optional[grpc.Channel]): A ``Channel`` instance through
- which to make calls.
+ ignored if a ``channel`` instance is provided.
+ channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]):
+ A ``Channel`` instance through which to make calls, or a Callable
+ that constructs and returns one. If set to None, ``self.create_channel``
+ is used to create the channel. If a Callable is given, it will be called
+ with the same arguments as used in ``self.create_channel``.
api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
If provided, it overrides the ``host`` argument and tries to create
a mutual TLS channel with client SSL credentials from
@@ -97,11 +182,11 @@ def __init__(
private key bytes, both in PEM format. It is ignored if
``api_mtls_endpoint`` is None.
ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
- for the grpc channel. It is ignored if ``channel`` is provided.
+ for the grpc channel. It is ignored if a ``channel`` instance is provided.
client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]):
A callback to provide client certificate bytes and private key bytes,
both in PEM format. It is used to configure a mutual TLS channel. It is
- ignored if ``channel`` or ``ssl_channel_credentials`` is provided.
+ ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided.
quota_project_id (Optional[str]): An optional project to use for billing
and quota.
client_info (google.api_core.gapic_v1.client_info.ClientInfo):
@@ -128,9 +213,10 @@ def __init__(
if client_cert_source:
warnings.warn("client_cert_source is deprecated", DeprecationWarning)
- if channel:
+ if isinstance(channel, grpc.Channel):
# Ignore credentials if a channel was passed.
- credentials = False
+ credentials = None
+ self._ignore_credentials = True
# If a channel was explicitly provided, set it.
self._grpc_channel = channel
self._ssl_channel_credentials = None
@@ -165,10 +251,13 @@ def __init__(
quota_project_id=quota_project_id,
client_info=client_info,
always_use_jwt_access=always_use_jwt_access,
+ api_audience=api_audience,
)
if not self._grpc_channel:
- self._grpc_channel = type(self).create_channel(
+ # initialize with the provided callable or the default channel
+ channel_init = channel or type(self).create_channel
+ self._grpc_channel = channel_init(
self._host,
# use the credentials which are saved
credentials=self._credentials,
@@ -184,15 +273,20 @@ def __init__(
],
)
- # Wrap messages. This must be done after self._grpc_channel exists
+ self._interceptor = _LoggingClientInterceptor()
+ self._logged_channel = grpc.intercept_channel(
+ self._grpc_channel, self._interceptor
+ )
+
+ # Wrap messages. This must be done after self._logged_channel exists
self._prep_wrapped_messages(client_info)
@classmethod
def create_channel(
cls,
host: str = "bigtableadmin.googleapis.com",
- credentials: ga_credentials.Credentials = None,
- credentials_file: str = None,
+ credentials: Optional[ga_credentials.Credentials] = None,
+ credentials_file: Optional[str] = None,
scopes: Optional[Sequence[str]] = None,
quota_project_id: Optional[str] = None,
**kwargs,
@@ -205,9 +299,10 @@ def create_channel(
credentials identify this application to the service. If
none are specified, the client will attempt to ascertain
the credentials from the environment.
- credentials_file (Optional[str]): A file with credentials that can
+ credentials_file (Optional[str]): Deprecated. A file with credentials that can
be loaded with :func:`google.auth.load_credentials_from_file`.
- This argument is mutually exclusive with credentials.
+ This argument is mutually exclusive with credentials. This argument will be
+ removed in the next major version of this library.
scopes (Optional[Sequence[str]]): A optional list of scopes needed for this
service. These are only used when credentials are not specified and
are passed to :func:`google.auth.default`.
@@ -248,7 +343,9 @@ def operations_client(self) -> operations_v1.OperationsClient:
"""
# Quick check: Only create a new client if we do not already have one.
if self._operations_client is None:
- self._operations_client = operations_v1.OperationsClient(self.grpc_channel)
+ self._operations_client = operations_v1.OperationsClient(
+ self._logged_channel
+ )
# Return the client from cache.
return self._operations_client
@@ -274,7 +371,7 @@ def create_table(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "create_table" not in self._stubs:
- self._stubs["create_table"] = self.grpc_channel.unary_unary(
+ self._stubs["create_table"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/CreateTable",
request_serializer=bigtable_table_admin.CreateTableRequest.serialize,
response_deserializer=gba_table.Table.deserialize,
@@ -292,6 +389,7 @@ def create_table_from_snapshot(
Creates a new table from the specified snapshot. The
target table must not exist. The snapshot and the table
must be in the same instance.
+
Note: This is a private alpha release of Cloud Bigtable
snapshots. This feature is not currently available to
most Cloud Bigtable customers. This feature might be
@@ -310,7 +408,9 @@ def create_table_from_snapshot(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "create_table_from_snapshot" not in self._stubs:
- self._stubs["create_table_from_snapshot"] = self.grpc_channel.unary_unary(
+ self._stubs[
+ "create_table_from_snapshot"
+ ] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/CreateTableFromSnapshot",
request_serializer=bigtable_table_admin.CreateTableFromSnapshotRequest.serialize,
response_deserializer=operations_pb2.Operation.FromString,
@@ -339,7 +439,7 @@ def list_tables(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "list_tables" not in self._stubs:
- self._stubs["list_tables"] = self.grpc_channel.unary_unary(
+ self._stubs["list_tables"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/ListTables",
request_serializer=bigtable_table_admin.ListTablesRequest.serialize,
response_deserializer=bigtable_table_admin.ListTablesResponse.deserialize,
@@ -365,13 +465,39 @@ def get_table(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "get_table" not in self._stubs:
- self._stubs["get_table"] = self.grpc_channel.unary_unary(
+ self._stubs["get_table"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/GetTable",
request_serializer=bigtable_table_admin.GetTableRequest.serialize,
response_deserializer=table.Table.deserialize,
)
return self._stubs["get_table"]
+ @property
+ def update_table(
+ self,
+ ) -> Callable[[bigtable_table_admin.UpdateTableRequest], operations_pb2.Operation]:
+ r"""Return a callable for the update table method over gRPC.
+
+ Updates a specified table.
+
+ Returns:
+ Callable[[~.UpdateTableRequest],
+ ~.Operation]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "update_table" not in self._stubs:
+ self._stubs["update_table"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableTableAdmin/UpdateTable",
+ request_serializer=bigtable_table_admin.UpdateTableRequest.serialize,
+ response_deserializer=operations_pb2.Operation.FromString,
+ )
+ return self._stubs["update_table"]
+
@property
def delete_table(
self,
@@ -392,13 +518,181 @@ def delete_table(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "delete_table" not in self._stubs:
- self._stubs["delete_table"] = self.grpc_channel.unary_unary(
+ self._stubs["delete_table"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/DeleteTable",
request_serializer=bigtable_table_admin.DeleteTableRequest.serialize,
response_deserializer=empty_pb2.Empty.FromString,
)
return self._stubs["delete_table"]
+ @property
+ def undelete_table(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.UndeleteTableRequest], operations_pb2.Operation
+ ]:
+ r"""Return a callable for the undelete table method over gRPC.
+
+ Restores a specified table which was accidentally
+ deleted.
+
+ Returns:
+ Callable[[~.UndeleteTableRequest],
+ ~.Operation]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "undelete_table" not in self._stubs:
+ self._stubs["undelete_table"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableTableAdmin/UndeleteTable",
+ request_serializer=bigtable_table_admin.UndeleteTableRequest.serialize,
+ response_deserializer=operations_pb2.Operation.FromString,
+ )
+ return self._stubs["undelete_table"]
+
+ @property
+ def create_authorized_view(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.CreateAuthorizedViewRequest], operations_pb2.Operation
+ ]:
+ r"""Return a callable for the create authorized view method over gRPC.
+
+ Creates a new AuthorizedView in a table.
+
+ Returns:
+ Callable[[~.CreateAuthorizedViewRequest],
+ ~.Operation]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "create_authorized_view" not in self._stubs:
+ self._stubs["create_authorized_view"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableTableAdmin/CreateAuthorizedView",
+ request_serializer=bigtable_table_admin.CreateAuthorizedViewRequest.serialize,
+ response_deserializer=operations_pb2.Operation.FromString,
+ )
+ return self._stubs["create_authorized_view"]
+
+ @property
+ def list_authorized_views(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.ListAuthorizedViewsRequest],
+ bigtable_table_admin.ListAuthorizedViewsResponse,
+ ]:
+ r"""Return a callable for the list authorized views method over gRPC.
+
+ Lists all AuthorizedViews from a specific table.
+
+ Returns:
+ Callable[[~.ListAuthorizedViewsRequest],
+ ~.ListAuthorizedViewsResponse]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "list_authorized_views" not in self._stubs:
+ self._stubs["list_authorized_views"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableTableAdmin/ListAuthorizedViews",
+ request_serializer=bigtable_table_admin.ListAuthorizedViewsRequest.serialize,
+ response_deserializer=bigtable_table_admin.ListAuthorizedViewsResponse.deserialize,
+ )
+ return self._stubs["list_authorized_views"]
+
+ @property
+ def get_authorized_view(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.GetAuthorizedViewRequest], table.AuthorizedView
+ ]:
+ r"""Return a callable for the get authorized view method over gRPC.
+
+ Gets information from a specified AuthorizedView.
+
+ Returns:
+ Callable[[~.GetAuthorizedViewRequest],
+ ~.AuthorizedView]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "get_authorized_view" not in self._stubs:
+ self._stubs["get_authorized_view"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableTableAdmin/GetAuthorizedView",
+ request_serializer=bigtable_table_admin.GetAuthorizedViewRequest.serialize,
+ response_deserializer=table.AuthorizedView.deserialize,
+ )
+ return self._stubs["get_authorized_view"]
+
+ @property
+ def update_authorized_view(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.UpdateAuthorizedViewRequest], operations_pb2.Operation
+ ]:
+ r"""Return a callable for the update authorized view method over gRPC.
+
+ Updates an AuthorizedView in a table.
+
+ Returns:
+ Callable[[~.UpdateAuthorizedViewRequest],
+ ~.Operation]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "update_authorized_view" not in self._stubs:
+ self._stubs["update_authorized_view"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableTableAdmin/UpdateAuthorizedView",
+ request_serializer=bigtable_table_admin.UpdateAuthorizedViewRequest.serialize,
+ response_deserializer=operations_pb2.Operation.FromString,
+ )
+ return self._stubs["update_authorized_view"]
+
+ @property
+ def delete_authorized_view(
+ self,
+ ) -> Callable[[bigtable_table_admin.DeleteAuthorizedViewRequest], empty_pb2.Empty]:
+ r"""Return a callable for the delete authorized view method over gRPC.
+
+ Permanently deletes a specified AuthorizedView.
+
+ Returns:
+ Callable[[~.DeleteAuthorizedViewRequest],
+ ~.Empty]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "delete_authorized_view" not in self._stubs:
+ self._stubs["delete_authorized_view"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableTableAdmin/DeleteAuthorizedView",
+ request_serializer=bigtable_table_admin.DeleteAuthorizedViewRequest.serialize,
+ response_deserializer=empty_pb2.Empty.FromString,
+ )
+ return self._stubs["delete_authorized_view"]
+
@property
def modify_column_families(
self,
@@ -422,7 +716,7 @@ def modify_column_families(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "modify_column_families" not in self._stubs:
- self._stubs["modify_column_families"] = self.grpc_channel.unary_unary(
+ self._stubs["modify_column_families"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/ModifyColumnFamilies",
request_serializer=bigtable_table_admin.ModifyColumnFamiliesRequest.serialize,
response_deserializer=table.Table.deserialize,
@@ -451,7 +745,7 @@ def drop_row_range(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "drop_row_range" not in self._stubs:
- self._stubs["drop_row_range"] = self.grpc_channel.unary_unary(
+ self._stubs["drop_row_range"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/DropRowRange",
request_serializer=bigtable_table_admin.DropRowRangeRequest.serialize,
response_deserializer=empty_pb2.Empty.FromString,
@@ -484,7 +778,9 @@ def generate_consistency_token(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "generate_consistency_token" not in self._stubs:
- self._stubs["generate_consistency_token"] = self.grpc_channel.unary_unary(
+ self._stubs[
+ "generate_consistency_token"
+ ] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/GenerateConsistencyToken",
request_serializer=bigtable_table_admin.GenerateConsistencyTokenRequest.serialize,
response_deserializer=bigtable_table_admin.GenerateConsistencyTokenResponse.deserialize,
@@ -516,7 +812,7 @@ def check_consistency(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "check_consistency" not in self._stubs:
- self._stubs["check_consistency"] = self.grpc_channel.unary_unary(
+ self._stubs["check_consistency"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/CheckConsistency",
request_serializer=bigtable_table_admin.CheckConsistencyRequest.serialize,
response_deserializer=bigtable_table_admin.CheckConsistencyResponse.deserialize,
@@ -534,6 +830,7 @@ def snapshot_table(
Creates a new snapshot in the specified cluster from
the specified source table. The cluster and the table
must be in the same instance.
+
Note: This is a private alpha release of Cloud Bigtable
snapshots. This feature is not currently available to
most Cloud Bigtable customers. This feature might be
@@ -552,7 +849,7 @@ def snapshot_table(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "snapshot_table" not in self._stubs:
- self._stubs["snapshot_table"] = self.grpc_channel.unary_unary(
+ self._stubs["snapshot_table"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/SnapshotTable",
request_serializer=bigtable_table_admin.SnapshotTableRequest.serialize,
response_deserializer=operations_pb2.Operation.FromString,
@@ -585,7 +882,7 @@ def get_snapshot(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "get_snapshot" not in self._stubs:
- self._stubs["get_snapshot"] = self.grpc_channel.unary_unary(
+ self._stubs["get_snapshot"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/GetSnapshot",
request_serializer=bigtable_table_admin.GetSnapshotRequest.serialize,
response_deserializer=table.Snapshot.deserialize,
@@ -621,7 +918,7 @@ def list_snapshots(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "list_snapshots" not in self._stubs:
- self._stubs["list_snapshots"] = self.grpc_channel.unary_unary(
+ self._stubs["list_snapshots"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/ListSnapshots",
request_serializer=bigtable_table_admin.ListSnapshotsRequest.serialize,
response_deserializer=bigtable_table_admin.ListSnapshotsResponse.deserialize,
@@ -635,6 +932,7 @@ def delete_snapshot(
r"""Return a callable for the delete snapshot method over gRPC.
Permanently deletes the specified snapshot.
+
Note: This is a private alpha release of Cloud Bigtable
snapshots. This feature is not currently available to
most Cloud Bigtable customers. This feature might be
@@ -653,7 +951,7 @@ def delete_snapshot(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "delete_snapshot" not in self._stubs:
- self._stubs["delete_snapshot"] = self.grpc_channel.unary_unary(
+ self._stubs["delete_snapshot"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/DeleteSnapshot",
request_serializer=bigtable_table_admin.DeleteSnapshotRequest.serialize,
response_deserializer=empty_pb2.Empty.FromString,
@@ -687,7 +985,7 @@ def create_backup(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "create_backup" not in self._stubs:
- self._stubs["create_backup"] = self.grpc_channel.unary_unary(
+ self._stubs["create_backup"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/CreateBackup",
request_serializer=bigtable_table_admin.CreateBackupRequest.serialize,
response_deserializer=operations_pb2.Operation.FromString,
@@ -714,7 +1012,7 @@ def get_backup(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "get_backup" not in self._stubs:
- self._stubs["get_backup"] = self.grpc_channel.unary_unary(
+ self._stubs["get_backup"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/GetBackup",
request_serializer=bigtable_table_admin.GetBackupRequest.serialize,
response_deserializer=table.Backup.deserialize,
@@ -740,7 +1038,7 @@ def update_backup(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "update_backup" not in self._stubs:
- self._stubs["update_backup"] = self.grpc_channel.unary_unary(
+ self._stubs["update_backup"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/UpdateBackup",
request_serializer=bigtable_table_admin.UpdateBackupRequest.serialize,
response_deserializer=table.Backup.deserialize,
@@ -766,7 +1064,7 @@ def delete_backup(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "delete_backup" not in self._stubs:
- self._stubs["delete_backup"] = self.grpc_channel.unary_unary(
+ self._stubs["delete_backup"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/DeleteBackup",
request_serializer=bigtable_table_admin.DeleteBackupRequest.serialize,
response_deserializer=empty_pb2.Empty.FromString,
@@ -796,7 +1094,7 @@ def list_backups(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "list_backups" not in self._stubs:
- self._stubs["list_backups"] = self.grpc_channel.unary_unary(
+ self._stubs["list_backups"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/ListBackups",
request_serializer=bigtable_table_admin.ListBackupsRequest.serialize,
response_deserializer=bigtable_table_admin.ListBackupsResponse.deserialize,
@@ -809,13 +1107,12 @@ def restore_table(
) -> Callable[[bigtable_table_admin.RestoreTableRequest], operations_pb2.Operation]:
r"""Return a callable for the restore table method over gRPC.
- Create a new table by restoring from a completed backup. The new
- table must be in the same project as the instance containing the
- backup. The returned table [long-running
+ Create a new table by restoring from a completed backup. The
+ returned table [long-running
operation][google.longrunning.Operation] can be used to track
the progress of the operation, and to cancel it. The
[metadata][google.longrunning.Operation.metadata] field type is
- [RestoreTableMetadata][google.bigtable.admin.RestoreTableMetadata].
+ [RestoreTableMetadata][google.bigtable.admin.v2.RestoreTableMetadata].
The [response][google.longrunning.Operation.response] type is
[Table][google.bigtable.admin.v2.Table], if successful.
@@ -830,20 +1127,48 @@ def restore_table(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "restore_table" not in self._stubs:
- self._stubs["restore_table"] = self.grpc_channel.unary_unary(
+ self._stubs["restore_table"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/RestoreTable",
request_serializer=bigtable_table_admin.RestoreTableRequest.serialize,
response_deserializer=operations_pb2.Operation.FromString,
)
return self._stubs["restore_table"]
+ @property
+ def copy_backup(
+ self,
+ ) -> Callable[[bigtable_table_admin.CopyBackupRequest], operations_pb2.Operation]:
+ r"""Return a callable for the copy backup method over gRPC.
+
+ Copy a Cloud Bigtable backup to a new backup in the
+ destination cluster located in the destination instance
+ and project.
+
+ Returns:
+ Callable[[~.CopyBackupRequest],
+ ~.Operation]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "copy_backup" not in self._stubs:
+ self._stubs["copy_backup"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableTableAdmin/CopyBackup",
+ request_serializer=bigtable_table_admin.CopyBackupRequest.serialize,
+ response_deserializer=operations_pb2.Operation.FromString,
+ )
+ return self._stubs["copy_backup"]
+
@property
def get_iam_policy(
self,
) -> Callable[[iam_policy_pb2.GetIamPolicyRequest], policy_pb2.Policy]:
r"""Return a callable for the get iam policy method over gRPC.
- Gets the access control policy for a Table or Backup
+ Gets the access control policy for a Bigtable
resource. Returns an empty policy if the resource exists
but does not have a policy set.
@@ -858,7 +1183,7 @@ def get_iam_policy(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "get_iam_policy" not in self._stubs:
- self._stubs["get_iam_policy"] = self.grpc_channel.unary_unary(
+ self._stubs["get_iam_policy"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/GetIamPolicy",
request_serializer=iam_policy_pb2.GetIamPolicyRequest.SerializeToString,
response_deserializer=policy_pb2.Policy.FromString,
@@ -871,7 +1196,7 @@ def set_iam_policy(
) -> Callable[[iam_policy_pb2.SetIamPolicyRequest], policy_pb2.Policy]:
r"""Return a callable for the set iam policy method over gRPC.
- Sets the access control policy on a Table or Backup
+ Sets the access control policy on a Bigtable
resource. Replaces any existing policy.
Returns:
@@ -885,7 +1210,7 @@ def set_iam_policy(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "set_iam_policy" not in self._stubs:
- self._stubs["set_iam_policy"] = self.grpc_channel.unary_unary(
+ self._stubs["set_iam_policy"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/SetIamPolicy",
request_serializer=iam_policy_pb2.SetIamPolicyRequest.SerializeToString,
response_deserializer=policy_pb2.Policy.FromString,
@@ -902,7 +1227,7 @@ def test_iam_permissions(
r"""Return a callable for the test iam permissions method over gRPC.
Returns permissions that the caller has on the
- specified Table or Backup resource.
+ specified Bigtable resource.
Returns:
Callable[[~.TestIamPermissionsRequest],
@@ -915,15 +1240,154 @@ def test_iam_permissions(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "test_iam_permissions" not in self._stubs:
- self._stubs["test_iam_permissions"] = self.grpc_channel.unary_unary(
+ self._stubs["test_iam_permissions"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/TestIamPermissions",
request_serializer=iam_policy_pb2.TestIamPermissionsRequest.SerializeToString,
response_deserializer=iam_policy_pb2.TestIamPermissionsResponse.FromString,
)
return self._stubs["test_iam_permissions"]
+ @property
+ def create_schema_bundle(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.CreateSchemaBundleRequest], operations_pb2.Operation
+ ]:
+ r"""Return a callable for the create schema bundle method over gRPC.
+
+ Creates a new schema bundle in the specified table.
+
+ Returns:
+ Callable[[~.CreateSchemaBundleRequest],
+ ~.Operation]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "create_schema_bundle" not in self._stubs:
+ self._stubs["create_schema_bundle"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableTableAdmin/CreateSchemaBundle",
+ request_serializer=bigtable_table_admin.CreateSchemaBundleRequest.serialize,
+ response_deserializer=operations_pb2.Operation.FromString,
+ )
+ return self._stubs["create_schema_bundle"]
+
+ @property
+ def update_schema_bundle(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.UpdateSchemaBundleRequest], operations_pb2.Operation
+ ]:
+ r"""Return a callable for the update schema bundle method over gRPC.
+
+ Updates a schema bundle in the specified table.
+
+ Returns:
+ Callable[[~.UpdateSchemaBundleRequest],
+ ~.Operation]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "update_schema_bundle" not in self._stubs:
+ self._stubs["update_schema_bundle"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableTableAdmin/UpdateSchemaBundle",
+ request_serializer=bigtable_table_admin.UpdateSchemaBundleRequest.serialize,
+ response_deserializer=operations_pb2.Operation.FromString,
+ )
+ return self._stubs["update_schema_bundle"]
+
+ @property
+ def get_schema_bundle(
+ self,
+ ) -> Callable[[bigtable_table_admin.GetSchemaBundleRequest], table.SchemaBundle]:
+ r"""Return a callable for the get schema bundle method over gRPC.
+
+ Gets metadata information about the specified schema
+ bundle.
+
+ Returns:
+ Callable[[~.GetSchemaBundleRequest],
+ ~.SchemaBundle]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "get_schema_bundle" not in self._stubs:
+ self._stubs["get_schema_bundle"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableTableAdmin/GetSchemaBundle",
+ request_serializer=bigtable_table_admin.GetSchemaBundleRequest.serialize,
+ response_deserializer=table.SchemaBundle.deserialize,
+ )
+ return self._stubs["get_schema_bundle"]
+
+ @property
+ def list_schema_bundles(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.ListSchemaBundlesRequest],
+ bigtable_table_admin.ListSchemaBundlesResponse,
+ ]:
+ r"""Return a callable for the list schema bundles method over gRPC.
+
+ Lists all schema bundles associated with the
+ specified table.
+
+ Returns:
+ Callable[[~.ListSchemaBundlesRequest],
+ ~.ListSchemaBundlesResponse]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "list_schema_bundles" not in self._stubs:
+ self._stubs["list_schema_bundles"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableTableAdmin/ListSchemaBundles",
+ request_serializer=bigtable_table_admin.ListSchemaBundlesRequest.serialize,
+ response_deserializer=bigtable_table_admin.ListSchemaBundlesResponse.deserialize,
+ )
+ return self._stubs["list_schema_bundles"]
+
+ @property
+ def delete_schema_bundle(
+ self,
+ ) -> Callable[[bigtable_table_admin.DeleteSchemaBundleRequest], empty_pb2.Empty]:
+ r"""Return a callable for the delete schema bundle method over gRPC.
+
+ Deletes a schema bundle in the specified table.
+
+ Returns:
+ Callable[[~.DeleteSchemaBundleRequest],
+ ~.Empty]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "delete_schema_bundle" not in self._stubs:
+ self._stubs["delete_schema_bundle"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableTableAdmin/DeleteSchemaBundle",
+ request_serializer=bigtable_table_admin.DeleteSchemaBundleRequest.serialize,
+ response_deserializer=empty_pb2.Empty.FromString,
+ )
+ return self._stubs["delete_schema_bundle"]
+
def close(self):
- self.grpc_channel.close()
+ self._logged_channel.close()
@property
def kind(self) -> str:
diff --git a/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/grpc_asyncio.py b/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/grpc_asyncio.py
index 7d2077f23..5017f17d0 100644
--- a/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/grpc_asyncio.py
+++ b/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/grpc_asyncio.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -13,16 +13,25 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+import inspect
+import json
+import pickle
+import logging as std_logging
import warnings
from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union
from google.api_core import gapic_v1
from google.api_core import grpc_helpers_async
+from google.api_core import exceptions as core_exceptions
+from google.api_core import retry_async as retries
from google.api_core import operations_v1
from google.auth import credentials as ga_credentials # type: ignore
from google.auth.transport.grpc import SslCredentials # type: ignore
+from google.protobuf.json_format import MessageToJson
+import google.protobuf.message
import grpc # type: ignore
+import proto # type: ignore
from grpc.experimental import aio # type: ignore
from google.cloud.bigtable_admin_v2.types import bigtable_table_admin
@@ -35,6 +44,82 @@
from .base import BigtableTableAdminTransport, DEFAULT_CLIENT_INFO
from .grpc import BigtableTableAdminGrpcTransport
+try:
+ from google.api_core import client_logging # type: ignore
+
+ CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER
+except ImportError: # pragma: NO COVER
+ CLIENT_LOGGING_SUPPORTED = False
+
+_LOGGER = std_logging.getLogger(__name__)
+
+
+class _LoggingClientAIOInterceptor(
+ grpc.aio.UnaryUnaryClientInterceptor
+): # pragma: NO COVER
+ async def intercept_unary_unary(self, continuation, client_call_details, request):
+ logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ std_logging.DEBUG
+ )
+ if logging_enabled: # pragma: NO COVER
+ request_metadata = client_call_details.metadata
+ if isinstance(request, proto.Message):
+ request_payload = type(request).to_json(request)
+ elif isinstance(request, google.protobuf.message.Message):
+ request_payload = MessageToJson(request)
+ else:
+ request_payload = f"{type(request).__name__}: {pickle.dumps(request)}"
+
+ request_metadata = {
+ key: value.decode("utf-8") if isinstance(value, bytes) else value
+ for key, value in request_metadata
+ }
+ grpc_request = {
+ "payload": request_payload,
+ "requestMethod": "grpc",
+ "metadata": dict(request_metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for {client_call_details.method}",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": str(client_call_details.method),
+ "request": grpc_request,
+ "metadata": grpc_request["metadata"],
+ },
+ )
+ response = await continuation(client_call_details, request)
+ if logging_enabled: # pragma: NO COVER
+ response_metadata = await response.trailing_metadata()
+ # Convert gRPC metadata `` to list of tuples
+ metadata = (
+ dict([(k, str(v)) for k, v in response_metadata])
+ if response_metadata
+ else None
+ )
+ result = await response
+ if isinstance(result, proto.Message):
+ response_payload = type(result).to_json(result)
+ elif isinstance(result, google.protobuf.message.Message):
+ response_payload = MessageToJson(result)
+ else:
+ response_payload = f"{type(result).__name__}: {pickle.dumps(result)}"
+ grpc_response = {
+ "payload": response_payload,
+ "metadata": metadata,
+ "status": "OK",
+ }
+ _LOGGER.debug(
+ f"Received response to rpc {client_call_details.method}.",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": str(client_call_details.method),
+ "response": grpc_response,
+ "metadata": grpc_response["metadata"],
+ },
+ )
+ return response
+
class BigtableTableAdminGrpcAsyncIOTransport(BigtableTableAdminTransport):
"""gRPC AsyncIO backend transport for BigtableTableAdmin.
@@ -60,7 +145,7 @@ class BigtableTableAdminGrpcAsyncIOTransport(BigtableTableAdminTransport):
def create_channel(
cls,
host: str = "bigtableadmin.googleapis.com",
- credentials: ga_credentials.Credentials = None,
+ credentials: Optional[ga_credentials.Credentials] = None,
credentials_file: Optional[str] = None,
scopes: Optional[Sequence[str]] = None,
quota_project_id: Optional[str] = None,
@@ -74,9 +159,9 @@ def create_channel(
credentials identify this application to the service. If
none are specified, the client will attempt to ascertain
the credentials from the environment.
- credentials_file (Optional[str]): A file with credentials that can
- be loaded with :func:`google.auth.load_credentials_from_file`.
- This argument is ignored if ``channel`` is provided.
+ credentials_file (Optional[str]): Deprecated. A file with credentials that can
+ be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be
+ removed in the next major version of this library.
scopes (Optional[Sequence[str]]): A optional list of scopes needed for this
service. These are only used when credentials are not specified and
are passed to :func:`google.auth.default`.
@@ -103,37 +188,42 @@ def __init__(
self,
*,
host: str = "bigtableadmin.googleapis.com",
- credentials: ga_credentials.Credentials = None,
+ credentials: Optional[ga_credentials.Credentials] = None,
credentials_file: Optional[str] = None,
scopes: Optional[Sequence[str]] = None,
- channel: aio.Channel = None,
- api_mtls_endpoint: str = None,
- client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
- ssl_channel_credentials: grpc.ChannelCredentials = None,
- client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None,
- quota_project_id=None,
+ channel: Optional[Union[aio.Channel, Callable[..., aio.Channel]]] = None,
+ api_mtls_endpoint: Optional[str] = None,
+ client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None,
+ ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None,
+ client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None,
+ quota_project_id: Optional[str] = None,
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
always_use_jwt_access: Optional[bool] = False,
+ api_audience: Optional[str] = None,
) -> None:
"""Instantiate the transport.
Args:
host (Optional[str]):
- The hostname to connect to.
+ The hostname to connect to (default: 'bigtableadmin.googleapis.com').
credentials (Optional[google.auth.credentials.Credentials]): The
authorization credentials to attach to requests. These
credentials identify the application to the service; if none
are specified, the client will attempt to ascertain the
credentials from the environment.
- This argument is ignored if ``channel`` is provided.
- credentials_file (Optional[str]): A file with credentials that can
+ This argument is ignored if a ``channel`` instance is provided.
+ credentials_file (Optional[str]): Deprecated. A file with credentials that can
be loaded with :func:`google.auth.load_credentials_from_file`.
- This argument is ignored if ``channel`` is provided.
+ This argument is ignored if a ``channel`` instance is provided.
+ This argument will be removed in the next major version of this library.
scopes (Optional[Sequence[str]]): A optional list of scopes needed for this
service. These are only used when credentials are not specified and
are passed to :func:`google.auth.default`.
- channel (Optional[aio.Channel]): A ``Channel`` instance through
- which to make calls.
+ channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]):
+ A ``Channel`` instance through which to make calls, or a Callable
+ that constructs and returns one. If set to None, ``self.create_channel``
+ is used to create the channel. If a Callable is given, it will be called
+ with the same arguments as used in ``self.create_channel``.
api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
If provided, it overrides the ``host`` argument and tries to create
a mutual TLS channel with client SSL credentials from
@@ -143,11 +233,11 @@ def __init__(
private key bytes, both in PEM format. It is ignored if
``api_mtls_endpoint`` is None.
ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
- for the grpc channel. It is ignored if ``channel`` is provided.
+ for the grpc channel. It is ignored if a ``channel`` instance is provided.
client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]):
A callback to provide client certificate bytes and private key bytes,
both in PEM format. It is used to configure a mutual TLS channel. It is
- ignored if ``channel`` or ``ssl_channel_credentials`` is provided.
+ ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided.
quota_project_id (Optional[str]): An optional project to use for billing
and quota.
client_info (google.api_core.gapic_v1.client_info.ClientInfo):
@@ -174,9 +264,10 @@ def __init__(
if client_cert_source:
warnings.warn("client_cert_source is deprecated", DeprecationWarning)
- if channel:
+ if isinstance(channel, aio.Channel):
# Ignore credentials if a channel was passed.
- credentials = False
+ credentials = None
+ self._ignore_credentials = True
# If a channel was explicitly provided, set it.
self._grpc_channel = channel
self._ssl_channel_credentials = None
@@ -210,10 +301,13 @@ def __init__(
quota_project_id=quota_project_id,
client_info=client_info,
always_use_jwt_access=always_use_jwt_access,
+ api_audience=api_audience,
)
if not self._grpc_channel:
- self._grpc_channel = type(self).create_channel(
+ # initialize with the provided callable or the default channel
+ channel_init = channel or type(self).create_channel
+ self._grpc_channel = channel_init(
self._host,
# use the credentials which are saved
credentials=self._credentials,
@@ -229,7 +323,13 @@ def __init__(
],
)
- # Wrap messages. This must be done after self._grpc_channel exists
+ self._interceptor = _LoggingClientAIOInterceptor()
+ self._grpc_channel._unary_unary_interceptors.append(self._interceptor)
+ self._logged_channel = self._grpc_channel
+ self._wrap_with_kind = (
+ "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters
+ )
+ # Wrap messages. This must be done after self._logged_channel exists
self._prep_wrapped_messages(client_info)
@property
@@ -252,7 +352,7 @@ def operations_client(self) -> operations_v1.OperationsAsyncClient:
# Quick check: Only create a new client if we do not already have one.
if self._operations_client is None:
self._operations_client = operations_v1.OperationsAsyncClient(
- self.grpc_channel
+ self._logged_channel
)
# Return the client from cache.
@@ -281,7 +381,7 @@ def create_table(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "create_table" not in self._stubs:
- self._stubs["create_table"] = self.grpc_channel.unary_unary(
+ self._stubs["create_table"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/CreateTable",
request_serializer=bigtable_table_admin.CreateTableRequest.serialize,
response_deserializer=gba_table.Table.deserialize,
@@ -300,6 +400,7 @@ def create_table_from_snapshot(
Creates a new table from the specified snapshot. The
target table must not exist. The snapshot and the table
must be in the same instance.
+
Note: This is a private alpha release of Cloud Bigtable
snapshots. This feature is not currently available to
most Cloud Bigtable customers. This feature might be
@@ -318,7 +419,9 @@ def create_table_from_snapshot(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "create_table_from_snapshot" not in self._stubs:
- self._stubs["create_table_from_snapshot"] = self.grpc_channel.unary_unary(
+ self._stubs[
+ "create_table_from_snapshot"
+ ] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/CreateTableFromSnapshot",
request_serializer=bigtable_table_admin.CreateTableFromSnapshotRequest.serialize,
response_deserializer=operations_pb2.Operation.FromString,
@@ -347,7 +450,7 @@ def list_tables(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "list_tables" not in self._stubs:
- self._stubs["list_tables"] = self.grpc_channel.unary_unary(
+ self._stubs["list_tables"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/ListTables",
request_serializer=bigtable_table_admin.ListTablesRequest.serialize,
response_deserializer=bigtable_table_admin.ListTablesResponse.deserialize,
@@ -373,13 +476,41 @@ def get_table(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "get_table" not in self._stubs:
- self._stubs["get_table"] = self.grpc_channel.unary_unary(
+ self._stubs["get_table"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/GetTable",
request_serializer=bigtable_table_admin.GetTableRequest.serialize,
response_deserializer=table.Table.deserialize,
)
return self._stubs["get_table"]
+ @property
+ def update_table(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.UpdateTableRequest], Awaitable[operations_pb2.Operation]
+ ]:
+ r"""Return a callable for the update table method over gRPC.
+
+ Updates a specified table.
+
+ Returns:
+ Callable[[~.UpdateTableRequest],
+ Awaitable[~.Operation]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "update_table" not in self._stubs:
+ self._stubs["update_table"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableTableAdmin/UpdateTable",
+ request_serializer=bigtable_table_admin.UpdateTableRequest.serialize,
+ response_deserializer=operations_pb2.Operation.FromString,
+ )
+ return self._stubs["update_table"]
+
@property
def delete_table(
self,
@@ -402,13 +533,185 @@ def delete_table(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "delete_table" not in self._stubs:
- self._stubs["delete_table"] = self.grpc_channel.unary_unary(
+ self._stubs["delete_table"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/DeleteTable",
request_serializer=bigtable_table_admin.DeleteTableRequest.serialize,
response_deserializer=empty_pb2.Empty.FromString,
)
return self._stubs["delete_table"]
+ @property
+ def undelete_table(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.UndeleteTableRequest], Awaitable[operations_pb2.Operation]
+ ]:
+ r"""Return a callable for the undelete table method over gRPC.
+
+ Restores a specified table which was accidentally
+ deleted.
+
+ Returns:
+ Callable[[~.UndeleteTableRequest],
+ Awaitable[~.Operation]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "undelete_table" not in self._stubs:
+ self._stubs["undelete_table"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableTableAdmin/UndeleteTable",
+ request_serializer=bigtable_table_admin.UndeleteTableRequest.serialize,
+ response_deserializer=operations_pb2.Operation.FromString,
+ )
+ return self._stubs["undelete_table"]
+
+ @property
+ def create_authorized_view(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.CreateAuthorizedViewRequest],
+ Awaitable[operations_pb2.Operation],
+ ]:
+ r"""Return a callable for the create authorized view method over gRPC.
+
+ Creates a new AuthorizedView in a table.
+
+ Returns:
+ Callable[[~.CreateAuthorizedViewRequest],
+ Awaitable[~.Operation]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "create_authorized_view" not in self._stubs:
+ self._stubs["create_authorized_view"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableTableAdmin/CreateAuthorizedView",
+ request_serializer=bigtable_table_admin.CreateAuthorizedViewRequest.serialize,
+ response_deserializer=operations_pb2.Operation.FromString,
+ )
+ return self._stubs["create_authorized_view"]
+
+ @property
+ def list_authorized_views(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.ListAuthorizedViewsRequest],
+ Awaitable[bigtable_table_admin.ListAuthorizedViewsResponse],
+ ]:
+ r"""Return a callable for the list authorized views method over gRPC.
+
+ Lists all AuthorizedViews from a specific table.
+
+ Returns:
+ Callable[[~.ListAuthorizedViewsRequest],
+ Awaitable[~.ListAuthorizedViewsResponse]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "list_authorized_views" not in self._stubs:
+ self._stubs["list_authorized_views"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableTableAdmin/ListAuthorizedViews",
+ request_serializer=bigtable_table_admin.ListAuthorizedViewsRequest.serialize,
+ response_deserializer=bigtable_table_admin.ListAuthorizedViewsResponse.deserialize,
+ )
+ return self._stubs["list_authorized_views"]
+
+ @property
+ def get_authorized_view(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.GetAuthorizedViewRequest], Awaitable[table.AuthorizedView]
+ ]:
+ r"""Return a callable for the get authorized view method over gRPC.
+
+ Gets information from a specified AuthorizedView.
+
+ Returns:
+ Callable[[~.GetAuthorizedViewRequest],
+ Awaitable[~.AuthorizedView]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "get_authorized_view" not in self._stubs:
+ self._stubs["get_authorized_view"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableTableAdmin/GetAuthorizedView",
+ request_serializer=bigtable_table_admin.GetAuthorizedViewRequest.serialize,
+ response_deserializer=table.AuthorizedView.deserialize,
+ )
+ return self._stubs["get_authorized_view"]
+
+ @property
+ def update_authorized_view(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.UpdateAuthorizedViewRequest],
+ Awaitable[operations_pb2.Operation],
+ ]:
+ r"""Return a callable for the update authorized view method over gRPC.
+
+ Updates an AuthorizedView in a table.
+
+ Returns:
+ Callable[[~.UpdateAuthorizedViewRequest],
+ Awaitable[~.Operation]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "update_authorized_view" not in self._stubs:
+ self._stubs["update_authorized_view"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableTableAdmin/UpdateAuthorizedView",
+ request_serializer=bigtable_table_admin.UpdateAuthorizedViewRequest.serialize,
+ response_deserializer=operations_pb2.Operation.FromString,
+ )
+ return self._stubs["update_authorized_view"]
+
+ @property
+ def delete_authorized_view(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.DeleteAuthorizedViewRequest], Awaitable[empty_pb2.Empty]
+ ]:
+ r"""Return a callable for the delete authorized view method over gRPC.
+
+ Permanently deletes a specified AuthorizedView.
+
+ Returns:
+ Callable[[~.DeleteAuthorizedViewRequest],
+ Awaitable[~.Empty]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "delete_authorized_view" not in self._stubs:
+ self._stubs["delete_authorized_view"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableTableAdmin/DeleteAuthorizedView",
+ request_serializer=bigtable_table_admin.DeleteAuthorizedViewRequest.serialize,
+ response_deserializer=empty_pb2.Empty.FromString,
+ )
+ return self._stubs["delete_authorized_view"]
+
@property
def modify_column_families(
self,
@@ -434,7 +737,7 @@ def modify_column_families(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "modify_column_families" not in self._stubs:
- self._stubs["modify_column_families"] = self.grpc_channel.unary_unary(
+ self._stubs["modify_column_families"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/ModifyColumnFamilies",
request_serializer=bigtable_table_admin.ModifyColumnFamiliesRequest.serialize,
response_deserializer=table.Table.deserialize,
@@ -465,7 +768,7 @@ def drop_row_range(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "drop_row_range" not in self._stubs:
- self._stubs["drop_row_range"] = self.grpc_channel.unary_unary(
+ self._stubs["drop_row_range"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/DropRowRange",
request_serializer=bigtable_table_admin.DropRowRangeRequest.serialize,
response_deserializer=empty_pb2.Empty.FromString,
@@ -498,7 +801,9 @@ def generate_consistency_token(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "generate_consistency_token" not in self._stubs:
- self._stubs["generate_consistency_token"] = self.grpc_channel.unary_unary(
+ self._stubs[
+ "generate_consistency_token"
+ ] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/GenerateConsistencyToken",
request_serializer=bigtable_table_admin.GenerateConsistencyTokenRequest.serialize,
response_deserializer=bigtable_table_admin.GenerateConsistencyTokenResponse.deserialize,
@@ -530,7 +835,7 @@ def check_consistency(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "check_consistency" not in self._stubs:
- self._stubs["check_consistency"] = self.grpc_channel.unary_unary(
+ self._stubs["check_consistency"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/CheckConsistency",
request_serializer=bigtable_table_admin.CheckConsistencyRequest.serialize,
response_deserializer=bigtable_table_admin.CheckConsistencyResponse.deserialize,
@@ -548,6 +853,7 @@ def snapshot_table(
Creates a new snapshot in the specified cluster from
the specified source table. The cluster and the table
must be in the same instance.
+
Note: This is a private alpha release of Cloud Bigtable
snapshots. This feature is not currently available to
most Cloud Bigtable customers. This feature might be
@@ -566,7 +872,7 @@ def snapshot_table(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "snapshot_table" not in self._stubs:
- self._stubs["snapshot_table"] = self.grpc_channel.unary_unary(
+ self._stubs["snapshot_table"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/SnapshotTable",
request_serializer=bigtable_table_admin.SnapshotTableRequest.serialize,
response_deserializer=operations_pb2.Operation.FromString,
@@ -599,7 +905,7 @@ def get_snapshot(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "get_snapshot" not in self._stubs:
- self._stubs["get_snapshot"] = self.grpc_channel.unary_unary(
+ self._stubs["get_snapshot"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/GetSnapshot",
request_serializer=bigtable_table_admin.GetSnapshotRequest.serialize,
response_deserializer=table.Snapshot.deserialize,
@@ -635,7 +941,7 @@ def list_snapshots(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "list_snapshots" not in self._stubs:
- self._stubs["list_snapshots"] = self.grpc_channel.unary_unary(
+ self._stubs["list_snapshots"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/ListSnapshots",
request_serializer=bigtable_table_admin.ListSnapshotsRequest.serialize,
response_deserializer=bigtable_table_admin.ListSnapshotsResponse.deserialize,
@@ -651,6 +957,7 @@ def delete_snapshot(
r"""Return a callable for the delete snapshot method over gRPC.
Permanently deletes the specified snapshot.
+
Note: This is a private alpha release of Cloud Bigtable
snapshots. This feature is not currently available to
most Cloud Bigtable customers. This feature might be
@@ -669,7 +976,7 @@ def delete_snapshot(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "delete_snapshot" not in self._stubs:
- self._stubs["delete_snapshot"] = self.grpc_channel.unary_unary(
+ self._stubs["delete_snapshot"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/DeleteSnapshot",
request_serializer=bigtable_table_admin.DeleteSnapshotRequest.serialize,
response_deserializer=empty_pb2.Empty.FromString,
@@ -705,7 +1012,7 @@ def create_backup(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "create_backup" not in self._stubs:
- self._stubs["create_backup"] = self.grpc_channel.unary_unary(
+ self._stubs["create_backup"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/CreateBackup",
request_serializer=bigtable_table_admin.CreateBackupRequest.serialize,
response_deserializer=operations_pb2.Operation.FromString,
@@ -732,7 +1039,7 @@ def get_backup(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "get_backup" not in self._stubs:
- self._stubs["get_backup"] = self.grpc_channel.unary_unary(
+ self._stubs["get_backup"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/GetBackup",
request_serializer=bigtable_table_admin.GetBackupRequest.serialize,
response_deserializer=table.Backup.deserialize,
@@ -758,7 +1065,7 @@ def update_backup(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "update_backup" not in self._stubs:
- self._stubs["update_backup"] = self.grpc_channel.unary_unary(
+ self._stubs["update_backup"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/UpdateBackup",
request_serializer=bigtable_table_admin.UpdateBackupRequest.serialize,
response_deserializer=table.Backup.deserialize,
@@ -786,7 +1093,7 @@ def delete_backup(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "delete_backup" not in self._stubs:
- self._stubs["delete_backup"] = self.grpc_channel.unary_unary(
+ self._stubs["delete_backup"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/DeleteBackup",
request_serializer=bigtable_table_admin.DeleteBackupRequest.serialize,
response_deserializer=empty_pb2.Empty.FromString,
@@ -816,7 +1123,7 @@ def list_backups(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "list_backups" not in self._stubs:
- self._stubs["list_backups"] = self.grpc_channel.unary_unary(
+ self._stubs["list_backups"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/ListBackups",
request_serializer=bigtable_table_admin.ListBackupsRequest.serialize,
response_deserializer=bigtable_table_admin.ListBackupsResponse.deserialize,
@@ -831,13 +1138,12 @@ def restore_table(
]:
r"""Return a callable for the restore table method over gRPC.
- Create a new table by restoring from a completed backup. The new
- table must be in the same project as the instance containing the
- backup. The returned table [long-running
+ Create a new table by restoring from a completed backup. The
+ returned table [long-running
operation][google.longrunning.Operation] can be used to track
the progress of the operation, and to cancel it. The
[metadata][google.longrunning.Operation.metadata] field type is
- [RestoreTableMetadata][google.bigtable.admin.RestoreTableMetadata].
+ [RestoreTableMetadata][google.bigtable.admin.v2.RestoreTableMetadata].
The [response][google.longrunning.Operation.response] type is
[Table][google.bigtable.admin.v2.Table], if successful.
@@ -852,20 +1158,50 @@ def restore_table(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "restore_table" not in self._stubs:
- self._stubs["restore_table"] = self.grpc_channel.unary_unary(
+ self._stubs["restore_table"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/RestoreTable",
request_serializer=bigtable_table_admin.RestoreTableRequest.serialize,
response_deserializer=operations_pb2.Operation.FromString,
)
return self._stubs["restore_table"]
+ @property
+ def copy_backup(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.CopyBackupRequest], Awaitable[operations_pb2.Operation]
+ ]:
+ r"""Return a callable for the copy backup method over gRPC.
+
+ Copy a Cloud Bigtable backup to a new backup in the
+ destination cluster located in the destination instance
+ and project.
+
+ Returns:
+ Callable[[~.CopyBackupRequest],
+ Awaitable[~.Operation]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "copy_backup" not in self._stubs:
+ self._stubs["copy_backup"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableTableAdmin/CopyBackup",
+ request_serializer=bigtable_table_admin.CopyBackupRequest.serialize,
+ response_deserializer=operations_pb2.Operation.FromString,
+ )
+ return self._stubs["copy_backup"]
+
@property
def get_iam_policy(
self,
) -> Callable[[iam_policy_pb2.GetIamPolicyRequest], Awaitable[policy_pb2.Policy]]:
r"""Return a callable for the get iam policy method over gRPC.
- Gets the access control policy for a Table or Backup
+ Gets the access control policy for a Bigtable
resource. Returns an empty policy if the resource exists
but does not have a policy set.
@@ -880,7 +1216,7 @@ def get_iam_policy(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "get_iam_policy" not in self._stubs:
- self._stubs["get_iam_policy"] = self.grpc_channel.unary_unary(
+ self._stubs["get_iam_policy"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/GetIamPolicy",
request_serializer=iam_policy_pb2.GetIamPolicyRequest.SerializeToString,
response_deserializer=policy_pb2.Policy.FromString,
@@ -893,7 +1229,7 @@ def set_iam_policy(
) -> Callable[[iam_policy_pb2.SetIamPolicyRequest], Awaitable[policy_pb2.Policy]]:
r"""Return a callable for the set iam policy method over gRPC.
- Sets the access control policy on a Table or Backup
+ Sets the access control policy on a Bigtable
resource. Replaces any existing policy.
Returns:
@@ -907,7 +1243,7 @@ def set_iam_policy(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "set_iam_policy" not in self._stubs:
- self._stubs["set_iam_policy"] = self.grpc_channel.unary_unary(
+ self._stubs["set_iam_policy"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/SetIamPolicy",
request_serializer=iam_policy_pb2.SetIamPolicyRequest.SerializeToString,
response_deserializer=policy_pb2.Policy.FromString,
@@ -924,7 +1260,7 @@ def test_iam_permissions(
r"""Return a callable for the test iam permissions method over gRPC.
Returns permissions that the caller has on the
- specified Table or Backup resource.
+ specified Bigtable resource.
Returns:
Callable[[~.TestIamPermissionsRequest],
@@ -937,15 +1273,449 @@ def test_iam_permissions(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "test_iam_permissions" not in self._stubs:
- self._stubs["test_iam_permissions"] = self.grpc_channel.unary_unary(
+ self._stubs["test_iam_permissions"] = self._logged_channel.unary_unary(
"/google.bigtable.admin.v2.BigtableTableAdmin/TestIamPermissions",
request_serializer=iam_policy_pb2.TestIamPermissionsRequest.SerializeToString,
response_deserializer=iam_policy_pb2.TestIamPermissionsResponse.FromString,
)
return self._stubs["test_iam_permissions"]
+ @property
+ def create_schema_bundle(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.CreateSchemaBundleRequest],
+ Awaitable[operations_pb2.Operation],
+ ]:
+ r"""Return a callable for the create schema bundle method over gRPC.
+
+ Creates a new schema bundle in the specified table.
+
+ Returns:
+ Callable[[~.CreateSchemaBundleRequest],
+ Awaitable[~.Operation]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "create_schema_bundle" not in self._stubs:
+ self._stubs["create_schema_bundle"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableTableAdmin/CreateSchemaBundle",
+ request_serializer=bigtable_table_admin.CreateSchemaBundleRequest.serialize,
+ response_deserializer=operations_pb2.Operation.FromString,
+ )
+ return self._stubs["create_schema_bundle"]
+
+ @property
+ def update_schema_bundle(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.UpdateSchemaBundleRequest],
+ Awaitable[operations_pb2.Operation],
+ ]:
+ r"""Return a callable for the update schema bundle method over gRPC.
+
+ Updates a schema bundle in the specified table.
+
+ Returns:
+ Callable[[~.UpdateSchemaBundleRequest],
+ Awaitable[~.Operation]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "update_schema_bundle" not in self._stubs:
+ self._stubs["update_schema_bundle"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableTableAdmin/UpdateSchemaBundle",
+ request_serializer=bigtable_table_admin.UpdateSchemaBundleRequest.serialize,
+ response_deserializer=operations_pb2.Operation.FromString,
+ )
+ return self._stubs["update_schema_bundle"]
+
+ @property
+ def get_schema_bundle(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.GetSchemaBundleRequest], Awaitable[table.SchemaBundle]
+ ]:
+ r"""Return a callable for the get schema bundle method over gRPC.
+
+ Gets metadata information about the specified schema
+ bundle.
+
+ Returns:
+ Callable[[~.GetSchemaBundleRequest],
+ Awaitable[~.SchemaBundle]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "get_schema_bundle" not in self._stubs:
+ self._stubs["get_schema_bundle"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableTableAdmin/GetSchemaBundle",
+ request_serializer=bigtable_table_admin.GetSchemaBundleRequest.serialize,
+ response_deserializer=table.SchemaBundle.deserialize,
+ )
+ return self._stubs["get_schema_bundle"]
+
+ @property
+ def list_schema_bundles(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.ListSchemaBundlesRequest],
+ Awaitable[bigtable_table_admin.ListSchemaBundlesResponse],
+ ]:
+ r"""Return a callable for the list schema bundles method over gRPC.
+
+ Lists all schema bundles associated with the
+ specified table.
+
+ Returns:
+ Callable[[~.ListSchemaBundlesRequest],
+ Awaitable[~.ListSchemaBundlesResponse]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "list_schema_bundles" not in self._stubs:
+ self._stubs["list_schema_bundles"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableTableAdmin/ListSchemaBundles",
+ request_serializer=bigtable_table_admin.ListSchemaBundlesRequest.serialize,
+ response_deserializer=bigtable_table_admin.ListSchemaBundlesResponse.deserialize,
+ )
+ return self._stubs["list_schema_bundles"]
+
+ @property
+ def delete_schema_bundle(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.DeleteSchemaBundleRequest], Awaitable[empty_pb2.Empty]
+ ]:
+ r"""Return a callable for the delete schema bundle method over gRPC.
+
+ Deletes a schema bundle in the specified table.
+
+ Returns:
+ Callable[[~.DeleteSchemaBundleRequest],
+ Awaitable[~.Empty]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "delete_schema_bundle" not in self._stubs:
+ self._stubs["delete_schema_bundle"] = self._logged_channel.unary_unary(
+ "/google.bigtable.admin.v2.BigtableTableAdmin/DeleteSchemaBundle",
+ request_serializer=bigtable_table_admin.DeleteSchemaBundleRequest.serialize,
+ response_deserializer=empty_pb2.Empty.FromString,
+ )
+ return self._stubs["delete_schema_bundle"]
+
+ def _prep_wrapped_messages(self, client_info):
+ """Precompute the wrapped methods, overriding the base class method to use async wrappers."""
+ self._wrapped_methods = {
+ self.create_table: self._wrap_method(
+ self.create_table,
+ default_timeout=300.0,
+ client_info=client_info,
+ ),
+ self.create_table_from_snapshot: self._wrap_method(
+ self.create_table_from_snapshot,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.list_tables: self._wrap_method(
+ self.list_tables,
+ default_retry=retries.AsyncRetry(
+ initial=1.0,
+ maximum=60.0,
+ multiplier=2,
+ predicate=retries.if_exception_type(
+ core_exceptions.DeadlineExceeded,
+ core_exceptions.ServiceUnavailable,
+ ),
+ deadline=60.0,
+ ),
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.get_table: self._wrap_method(
+ self.get_table,
+ default_retry=retries.AsyncRetry(
+ initial=1.0,
+ maximum=60.0,
+ multiplier=2,
+ predicate=retries.if_exception_type(
+ core_exceptions.DeadlineExceeded,
+ core_exceptions.ServiceUnavailable,
+ ),
+ deadline=60.0,
+ ),
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.update_table: self._wrap_method(
+ self.update_table,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.delete_table: self._wrap_method(
+ self.delete_table,
+ default_timeout=300.0,
+ client_info=client_info,
+ ),
+ self.undelete_table: self._wrap_method(
+ self.undelete_table,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.create_authorized_view: self._wrap_method(
+ self.create_authorized_view,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.list_authorized_views: self._wrap_method(
+ self.list_authorized_views,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.get_authorized_view: self._wrap_method(
+ self.get_authorized_view,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.update_authorized_view: self._wrap_method(
+ self.update_authorized_view,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.delete_authorized_view: self._wrap_method(
+ self.delete_authorized_view,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.modify_column_families: self._wrap_method(
+ self.modify_column_families,
+ default_timeout=300.0,
+ client_info=client_info,
+ ),
+ self.drop_row_range: self._wrap_method(
+ self.drop_row_range,
+ default_timeout=3600.0,
+ client_info=client_info,
+ ),
+ self.generate_consistency_token: self._wrap_method(
+ self.generate_consistency_token,
+ default_retry=retries.AsyncRetry(
+ initial=1.0,
+ maximum=60.0,
+ multiplier=2,
+ predicate=retries.if_exception_type(
+ core_exceptions.DeadlineExceeded,
+ core_exceptions.ServiceUnavailable,
+ ),
+ deadline=60.0,
+ ),
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.check_consistency: self._wrap_method(
+ self.check_consistency,
+ default_retry=retries.AsyncRetry(
+ initial=1.0,
+ maximum=60.0,
+ multiplier=2,
+ predicate=retries.if_exception_type(
+ core_exceptions.DeadlineExceeded,
+ core_exceptions.ServiceUnavailable,
+ ),
+ deadline=3600.0,
+ ),
+ default_timeout=3600.0,
+ client_info=client_info,
+ ),
+ self.snapshot_table: self._wrap_method(
+ self.snapshot_table,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.get_snapshot: self._wrap_method(
+ self.get_snapshot,
+ default_retry=retries.AsyncRetry(
+ initial=1.0,
+ maximum=60.0,
+ multiplier=2,
+ predicate=retries.if_exception_type(
+ core_exceptions.DeadlineExceeded,
+ core_exceptions.ServiceUnavailable,
+ ),
+ deadline=60.0,
+ ),
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.list_snapshots: self._wrap_method(
+ self.list_snapshots,
+ default_retry=retries.AsyncRetry(
+ initial=1.0,
+ maximum=60.0,
+ multiplier=2,
+ predicate=retries.if_exception_type(
+ core_exceptions.DeadlineExceeded,
+ core_exceptions.ServiceUnavailable,
+ ),
+ deadline=60.0,
+ ),
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.delete_snapshot: self._wrap_method(
+ self.delete_snapshot,
+ default_timeout=300.0,
+ client_info=client_info,
+ ),
+ self.create_backup: self._wrap_method(
+ self.create_backup,
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.get_backup: self._wrap_method(
+ self.get_backup,
+ default_retry=retries.AsyncRetry(
+ initial=1.0,
+ maximum=60.0,
+ multiplier=2,
+ predicate=retries.if_exception_type(
+ core_exceptions.DeadlineExceeded,
+ core_exceptions.ServiceUnavailable,
+ ),
+ deadline=60.0,
+ ),
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.update_backup: self._wrap_method(
+ self.update_backup,
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.delete_backup: self._wrap_method(
+ self.delete_backup,
+ default_timeout=300.0,
+ client_info=client_info,
+ ),
+ self.list_backups: self._wrap_method(
+ self.list_backups,
+ default_retry=retries.AsyncRetry(
+ initial=1.0,
+ maximum=60.0,
+ multiplier=2,
+ predicate=retries.if_exception_type(
+ core_exceptions.DeadlineExceeded,
+ core_exceptions.ServiceUnavailable,
+ ),
+ deadline=60.0,
+ ),
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.restore_table: self._wrap_method(
+ self.restore_table,
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.copy_backup: self._wrap_method(
+ self.copy_backup,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.get_iam_policy: self._wrap_method(
+ self.get_iam_policy,
+ default_retry=retries.AsyncRetry(
+ initial=1.0,
+ maximum=60.0,
+ multiplier=2,
+ predicate=retries.if_exception_type(
+ core_exceptions.DeadlineExceeded,
+ core_exceptions.ServiceUnavailable,
+ ),
+ deadline=60.0,
+ ),
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.set_iam_policy: self._wrap_method(
+ self.set_iam_policy,
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.test_iam_permissions: self._wrap_method(
+ self.test_iam_permissions,
+ default_retry=retries.AsyncRetry(
+ initial=1.0,
+ maximum=60.0,
+ multiplier=2,
+ predicate=retries.if_exception_type(
+ core_exceptions.DeadlineExceeded,
+ core_exceptions.ServiceUnavailable,
+ ),
+ deadline=60.0,
+ ),
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.create_schema_bundle: self._wrap_method(
+ self.create_schema_bundle,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.update_schema_bundle: self._wrap_method(
+ self.update_schema_bundle,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.get_schema_bundle: self._wrap_method(
+ self.get_schema_bundle,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.list_schema_bundles: self._wrap_method(
+ self.list_schema_bundles,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.delete_schema_bundle: self._wrap_method(
+ self.delete_schema_bundle,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ }
+
+ def _wrap_method(self, func, *args, **kwargs):
+ if self._wrap_with_kind: # pragma: NO COVER
+ kwargs["kind"] = self.kind
+ return gapic_v1.method_async.wrap_method(func, *args, **kwargs)
+
def close(self):
- return self.grpc_channel.close()
+ return self._logged_channel.close()
+
+ @property
+ def kind(self) -> str:
+ return "grpc_asyncio"
__all__ = ("BigtableTableAdminGrpcAsyncIOTransport",)
diff --git a/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/rest.py b/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/rest.py
new file mode 100644
index 000000000..6c3815f79
--- /dev/null
+++ b/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/rest.py
@@ -0,0 +1,7639 @@
+# -*- coding: utf-8 -*-
+# Copyright 2025 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 logging
+import json # type: ignore
+
+from google.auth.transport.requests import AuthorizedSession # type: ignore
+from google.auth import credentials as ga_credentials # type: ignore
+from google.api_core import exceptions as core_exceptions
+from google.api_core import retry as retries
+from google.api_core import rest_helpers
+from google.api_core import rest_streaming
+from google.api_core import gapic_v1
+import google.protobuf
+
+from google.protobuf import json_format
+from google.api_core import operations_v1
+
+from requests import __version__ as requests_version
+import dataclasses
+from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union
+import warnings
+
+
+from google.cloud.bigtable_admin_v2.types import bigtable_table_admin
+from google.cloud.bigtable_admin_v2.types import table
+from google.cloud.bigtable_admin_v2.types import table as gba_table
+from google.iam.v1 import iam_policy_pb2 # type: ignore
+from google.iam.v1 import policy_pb2 # type: ignore
+from google.protobuf import empty_pb2 # type: ignore
+from google.longrunning import operations_pb2 # type: ignore
+
+
+from .rest_base import _BaseBigtableTableAdminRestTransport
+from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO
+
+try:
+ OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None]
+except AttributeError: # pragma: NO COVER
+ OptionalRetry = Union[retries.Retry, object, None] # type: ignore
+
+try:
+ from google.api_core import client_logging # type: ignore
+
+ CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER
+except ImportError: # pragma: NO COVER
+ CLIENT_LOGGING_SUPPORTED = False
+
+_LOGGER = logging.getLogger(__name__)
+
+DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
+ gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version,
+ grpc_version=None,
+ rest_version=f"requests@{requests_version}",
+)
+
+if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER
+ DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__
+
+
+class BigtableTableAdminRestInterceptor:
+ """Interceptor for BigtableTableAdmin.
+
+ Interceptors are used to manipulate requests, request metadata, and responses
+ in arbitrary ways.
+ Example use cases include:
+ * Logging
+ * Verifying requests according to service or custom semantics
+ * Stripping extraneous information from responses
+
+ These use cases and more can be enabled by injecting an
+ instance of a custom subclass when constructing the BigtableTableAdminRestTransport.
+
+ .. code-block:: python
+ class MyCustomBigtableTableAdminInterceptor(BigtableTableAdminRestInterceptor):
+ def pre_check_consistency(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_check_consistency(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_copy_backup(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_copy_backup(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_create_authorized_view(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_create_authorized_view(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_create_backup(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_create_backup(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_create_schema_bundle(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_create_schema_bundle(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_create_table(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_create_table(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_create_table_from_snapshot(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_create_table_from_snapshot(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_delete_authorized_view(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def pre_delete_backup(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def pre_delete_schema_bundle(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def pre_delete_snapshot(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def pre_delete_table(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def pre_drop_row_range(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def pre_generate_consistency_token(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_generate_consistency_token(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_get_authorized_view(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_get_authorized_view(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_get_backup(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_get_backup(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_get_iam_policy(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_get_iam_policy(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_get_schema_bundle(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_get_schema_bundle(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_get_snapshot(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_get_snapshot(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_get_table(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_get_table(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_list_authorized_views(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_list_authorized_views(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_list_backups(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_list_backups(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_list_schema_bundles(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_list_schema_bundles(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_list_snapshots(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_list_snapshots(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_list_tables(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_list_tables(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_modify_column_families(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_modify_column_families(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_restore_table(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_restore_table(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_set_iam_policy(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_set_iam_policy(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_snapshot_table(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_snapshot_table(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_test_iam_permissions(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_test_iam_permissions(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_undelete_table(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_undelete_table(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_update_authorized_view(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_update_authorized_view(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_update_backup(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_update_backup(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_update_schema_bundle(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_update_schema_bundle(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_update_table(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_update_table(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ transport = BigtableTableAdminRestTransport(interceptor=MyCustomBigtableTableAdminInterceptor())
+ client = BaseBigtableTableAdminClient(transport=transport)
+
+
+ """
+
+ def pre_check_consistency(
+ self,
+ request: bigtable_table_admin.CheckConsistencyRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.CheckConsistencyRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for check_consistency
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def post_check_consistency(
+ self, response: bigtable_table_admin.CheckConsistencyResponse
+ ) -> bigtable_table_admin.CheckConsistencyResponse:
+ """Post-rpc interceptor for check_consistency
+
+ DEPRECATED. Please use the `post_check_consistency_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableTableAdmin server but before
+ it is returned to user code. This `post_check_consistency` interceptor runs
+ before the `post_check_consistency_with_metadata` interceptor.
+ """
+ return response
+
+ def post_check_consistency_with_metadata(
+ self,
+ response: bigtable_table_admin.CheckConsistencyResponse,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.CheckConsistencyResponse,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Post-rpc interceptor for check_consistency
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableTableAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_check_consistency_with_metadata`
+ interceptor in new development instead of the `post_check_consistency` interceptor.
+ When both interceptors are used, this `post_check_consistency_with_metadata` interceptor runs after the
+ `post_check_consistency` interceptor. The (possibly modified) response returned by
+ `post_check_consistency` will be passed to
+ `post_check_consistency_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_copy_backup(
+ self,
+ request: bigtable_table_admin.CopyBackupRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.CopyBackupRequest, Sequence[Tuple[str, Union[str, bytes]]]
+ ]:
+ """Pre-rpc interceptor for copy_backup
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def post_copy_backup(
+ self, response: operations_pb2.Operation
+ ) -> operations_pb2.Operation:
+ """Post-rpc interceptor for copy_backup
+
+ DEPRECATED. Please use the `post_copy_backup_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableTableAdmin server but before
+ it is returned to user code. This `post_copy_backup` interceptor runs
+ before the `post_copy_backup_with_metadata` interceptor.
+ """
+ return response
+
+ def post_copy_backup_with_metadata(
+ self,
+ response: operations_pb2.Operation,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for copy_backup
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableTableAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_copy_backup_with_metadata`
+ interceptor in new development instead of the `post_copy_backup` interceptor.
+ When both interceptors are used, this `post_copy_backup_with_metadata` interceptor runs after the
+ `post_copy_backup` interceptor. The (possibly modified) response returned by
+ `post_copy_backup` will be passed to
+ `post_copy_backup_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_create_authorized_view(
+ self,
+ request: bigtable_table_admin.CreateAuthorizedViewRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.CreateAuthorizedViewRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for create_authorized_view
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def post_create_authorized_view(
+ self, response: operations_pb2.Operation
+ ) -> operations_pb2.Operation:
+ """Post-rpc interceptor for create_authorized_view
+
+ DEPRECATED. Please use the `post_create_authorized_view_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableTableAdmin server but before
+ it is returned to user code. This `post_create_authorized_view` interceptor runs
+ before the `post_create_authorized_view_with_metadata` interceptor.
+ """
+ return response
+
+ def post_create_authorized_view_with_metadata(
+ self,
+ response: operations_pb2.Operation,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for create_authorized_view
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableTableAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_create_authorized_view_with_metadata`
+ interceptor in new development instead of the `post_create_authorized_view` interceptor.
+ When both interceptors are used, this `post_create_authorized_view_with_metadata` interceptor runs after the
+ `post_create_authorized_view` interceptor. The (possibly modified) response returned by
+ `post_create_authorized_view` will be passed to
+ `post_create_authorized_view_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_create_backup(
+ self,
+ request: bigtable_table_admin.CreateBackupRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.CreateBackupRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for create_backup
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def post_create_backup(
+ self, response: operations_pb2.Operation
+ ) -> operations_pb2.Operation:
+ """Post-rpc interceptor for create_backup
+
+ DEPRECATED. Please use the `post_create_backup_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableTableAdmin server but before
+ it is returned to user code. This `post_create_backup` interceptor runs
+ before the `post_create_backup_with_metadata` interceptor.
+ """
+ return response
+
+ def post_create_backup_with_metadata(
+ self,
+ response: operations_pb2.Operation,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for create_backup
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableTableAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_create_backup_with_metadata`
+ interceptor in new development instead of the `post_create_backup` interceptor.
+ When both interceptors are used, this `post_create_backup_with_metadata` interceptor runs after the
+ `post_create_backup` interceptor. The (possibly modified) response returned by
+ `post_create_backup` will be passed to
+ `post_create_backup_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_create_schema_bundle(
+ self,
+ request: bigtable_table_admin.CreateSchemaBundleRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.CreateSchemaBundleRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for create_schema_bundle
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def post_create_schema_bundle(
+ self, response: operations_pb2.Operation
+ ) -> operations_pb2.Operation:
+ """Post-rpc interceptor for create_schema_bundle
+
+ DEPRECATED. Please use the `post_create_schema_bundle_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableTableAdmin server but before
+ it is returned to user code. This `post_create_schema_bundle` interceptor runs
+ before the `post_create_schema_bundle_with_metadata` interceptor.
+ """
+ return response
+
+ def post_create_schema_bundle_with_metadata(
+ self,
+ response: operations_pb2.Operation,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for create_schema_bundle
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableTableAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_create_schema_bundle_with_metadata`
+ interceptor in new development instead of the `post_create_schema_bundle` interceptor.
+ When both interceptors are used, this `post_create_schema_bundle_with_metadata` interceptor runs after the
+ `post_create_schema_bundle` interceptor. The (possibly modified) response returned by
+ `post_create_schema_bundle` will be passed to
+ `post_create_schema_bundle_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_create_table(
+ self,
+ request: bigtable_table_admin.CreateTableRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.CreateTableRequest, Sequence[Tuple[str, Union[str, bytes]]]
+ ]:
+ """Pre-rpc interceptor for create_table
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def post_create_table(self, response: gba_table.Table) -> gba_table.Table:
+ """Post-rpc interceptor for create_table
+
+ DEPRECATED. Please use the `post_create_table_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableTableAdmin server but before
+ it is returned to user code. This `post_create_table` interceptor runs
+ before the `post_create_table_with_metadata` interceptor.
+ """
+ return response
+
+ def post_create_table_with_metadata(
+ self,
+ response: gba_table.Table,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[gba_table.Table, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for create_table
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableTableAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_create_table_with_metadata`
+ interceptor in new development instead of the `post_create_table` interceptor.
+ When both interceptors are used, this `post_create_table_with_metadata` interceptor runs after the
+ `post_create_table` interceptor. The (possibly modified) response returned by
+ `post_create_table` will be passed to
+ `post_create_table_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_create_table_from_snapshot(
+ self,
+ request: bigtable_table_admin.CreateTableFromSnapshotRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.CreateTableFromSnapshotRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for create_table_from_snapshot
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def post_create_table_from_snapshot(
+ self, response: operations_pb2.Operation
+ ) -> operations_pb2.Operation:
+ """Post-rpc interceptor for create_table_from_snapshot
+
+ DEPRECATED. Please use the `post_create_table_from_snapshot_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableTableAdmin server but before
+ it is returned to user code. This `post_create_table_from_snapshot` interceptor runs
+ before the `post_create_table_from_snapshot_with_metadata` interceptor.
+ """
+ return response
+
+ def post_create_table_from_snapshot_with_metadata(
+ self,
+ response: operations_pb2.Operation,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for create_table_from_snapshot
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableTableAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_create_table_from_snapshot_with_metadata`
+ interceptor in new development instead of the `post_create_table_from_snapshot` interceptor.
+ When both interceptors are used, this `post_create_table_from_snapshot_with_metadata` interceptor runs after the
+ `post_create_table_from_snapshot` interceptor. The (possibly modified) response returned by
+ `post_create_table_from_snapshot` will be passed to
+ `post_create_table_from_snapshot_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_delete_authorized_view(
+ self,
+ request: bigtable_table_admin.DeleteAuthorizedViewRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.DeleteAuthorizedViewRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for delete_authorized_view
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def pre_delete_backup(
+ self,
+ request: bigtable_table_admin.DeleteBackupRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.DeleteBackupRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for delete_backup
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def pre_delete_schema_bundle(
+ self,
+ request: bigtable_table_admin.DeleteSchemaBundleRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.DeleteSchemaBundleRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for delete_schema_bundle
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def pre_delete_snapshot(
+ self,
+ request: bigtable_table_admin.DeleteSnapshotRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.DeleteSnapshotRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for delete_snapshot
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def pre_delete_table(
+ self,
+ request: bigtable_table_admin.DeleteTableRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.DeleteTableRequest, Sequence[Tuple[str, Union[str, bytes]]]
+ ]:
+ """Pre-rpc interceptor for delete_table
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def pre_drop_row_range(
+ self,
+ request: bigtable_table_admin.DropRowRangeRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.DropRowRangeRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for drop_row_range
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def pre_generate_consistency_token(
+ self,
+ request: bigtable_table_admin.GenerateConsistencyTokenRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.GenerateConsistencyTokenRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for generate_consistency_token
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def post_generate_consistency_token(
+ self, response: bigtable_table_admin.GenerateConsistencyTokenResponse
+ ) -> bigtable_table_admin.GenerateConsistencyTokenResponse:
+ """Post-rpc interceptor for generate_consistency_token
+
+ DEPRECATED. Please use the `post_generate_consistency_token_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableTableAdmin server but before
+ it is returned to user code. This `post_generate_consistency_token` interceptor runs
+ before the `post_generate_consistency_token_with_metadata` interceptor.
+ """
+ return response
+
+ def post_generate_consistency_token_with_metadata(
+ self,
+ response: bigtable_table_admin.GenerateConsistencyTokenResponse,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.GenerateConsistencyTokenResponse,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Post-rpc interceptor for generate_consistency_token
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableTableAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_generate_consistency_token_with_metadata`
+ interceptor in new development instead of the `post_generate_consistency_token` interceptor.
+ When both interceptors are used, this `post_generate_consistency_token_with_metadata` interceptor runs after the
+ `post_generate_consistency_token` interceptor. The (possibly modified) response returned by
+ `post_generate_consistency_token` will be passed to
+ `post_generate_consistency_token_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_get_authorized_view(
+ self,
+ request: bigtable_table_admin.GetAuthorizedViewRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.GetAuthorizedViewRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for get_authorized_view
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def post_get_authorized_view(
+ self, response: table.AuthorizedView
+ ) -> table.AuthorizedView:
+ """Post-rpc interceptor for get_authorized_view
+
+ DEPRECATED. Please use the `post_get_authorized_view_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableTableAdmin server but before
+ it is returned to user code. This `post_get_authorized_view` interceptor runs
+ before the `post_get_authorized_view_with_metadata` interceptor.
+ """
+ return response
+
+ def post_get_authorized_view_with_metadata(
+ self,
+ response: table.AuthorizedView,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[table.AuthorizedView, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for get_authorized_view
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableTableAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_get_authorized_view_with_metadata`
+ interceptor in new development instead of the `post_get_authorized_view` interceptor.
+ When both interceptors are used, this `post_get_authorized_view_with_metadata` interceptor runs after the
+ `post_get_authorized_view` interceptor. The (possibly modified) response returned by
+ `post_get_authorized_view` will be passed to
+ `post_get_authorized_view_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_get_backup(
+ self,
+ request: bigtable_table_admin.GetBackupRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.GetBackupRequest, Sequence[Tuple[str, Union[str, bytes]]]
+ ]:
+ """Pre-rpc interceptor for get_backup
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def post_get_backup(self, response: table.Backup) -> table.Backup:
+ """Post-rpc interceptor for get_backup
+
+ DEPRECATED. Please use the `post_get_backup_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableTableAdmin server but before
+ it is returned to user code. This `post_get_backup` interceptor runs
+ before the `post_get_backup_with_metadata` interceptor.
+ """
+ return response
+
+ def post_get_backup_with_metadata(
+ self, response: table.Backup, metadata: Sequence[Tuple[str, Union[str, bytes]]]
+ ) -> Tuple[table.Backup, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for get_backup
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableTableAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_get_backup_with_metadata`
+ interceptor in new development instead of the `post_get_backup` interceptor.
+ When both interceptors are used, this `post_get_backup_with_metadata` interceptor runs after the
+ `post_get_backup` interceptor. The (possibly modified) response returned by
+ `post_get_backup` will be passed to
+ `post_get_backup_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_get_iam_policy(
+ self,
+ request: iam_policy_pb2.GetIamPolicyRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ iam_policy_pb2.GetIamPolicyRequest, Sequence[Tuple[str, Union[str, bytes]]]
+ ]:
+ """Pre-rpc interceptor for get_iam_policy
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def post_get_iam_policy(self, response: policy_pb2.Policy) -> policy_pb2.Policy:
+ """Post-rpc interceptor for get_iam_policy
+
+ DEPRECATED. Please use the `post_get_iam_policy_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableTableAdmin server but before
+ it is returned to user code. This `post_get_iam_policy` interceptor runs
+ before the `post_get_iam_policy_with_metadata` interceptor.
+ """
+ return response
+
+ def post_get_iam_policy_with_metadata(
+ self,
+ response: policy_pb2.Policy,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[policy_pb2.Policy, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for get_iam_policy
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableTableAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_get_iam_policy_with_metadata`
+ interceptor in new development instead of the `post_get_iam_policy` interceptor.
+ When both interceptors are used, this `post_get_iam_policy_with_metadata` interceptor runs after the
+ `post_get_iam_policy` interceptor. The (possibly modified) response returned by
+ `post_get_iam_policy` will be passed to
+ `post_get_iam_policy_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_get_schema_bundle(
+ self,
+ request: bigtable_table_admin.GetSchemaBundleRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.GetSchemaBundleRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for get_schema_bundle
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def post_get_schema_bundle(
+ self, response: table.SchemaBundle
+ ) -> table.SchemaBundle:
+ """Post-rpc interceptor for get_schema_bundle
+
+ DEPRECATED. Please use the `post_get_schema_bundle_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableTableAdmin server but before
+ it is returned to user code. This `post_get_schema_bundle` interceptor runs
+ before the `post_get_schema_bundle_with_metadata` interceptor.
+ """
+ return response
+
+ def post_get_schema_bundle_with_metadata(
+ self,
+ response: table.SchemaBundle,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[table.SchemaBundle, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for get_schema_bundle
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableTableAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_get_schema_bundle_with_metadata`
+ interceptor in new development instead of the `post_get_schema_bundle` interceptor.
+ When both interceptors are used, this `post_get_schema_bundle_with_metadata` interceptor runs after the
+ `post_get_schema_bundle` interceptor. The (possibly modified) response returned by
+ `post_get_schema_bundle` will be passed to
+ `post_get_schema_bundle_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_get_snapshot(
+ self,
+ request: bigtable_table_admin.GetSnapshotRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.GetSnapshotRequest, Sequence[Tuple[str, Union[str, bytes]]]
+ ]:
+ """Pre-rpc interceptor for get_snapshot
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def post_get_snapshot(self, response: table.Snapshot) -> table.Snapshot:
+ """Post-rpc interceptor for get_snapshot
+
+ DEPRECATED. Please use the `post_get_snapshot_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableTableAdmin server but before
+ it is returned to user code. This `post_get_snapshot` interceptor runs
+ before the `post_get_snapshot_with_metadata` interceptor.
+ """
+ return response
+
+ def post_get_snapshot_with_metadata(
+ self,
+ response: table.Snapshot,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[table.Snapshot, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for get_snapshot
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableTableAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_get_snapshot_with_metadata`
+ interceptor in new development instead of the `post_get_snapshot` interceptor.
+ When both interceptors are used, this `post_get_snapshot_with_metadata` interceptor runs after the
+ `post_get_snapshot` interceptor. The (possibly modified) response returned by
+ `post_get_snapshot` will be passed to
+ `post_get_snapshot_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_get_table(
+ self,
+ request: bigtable_table_admin.GetTableRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.GetTableRequest, Sequence[Tuple[str, Union[str, bytes]]]
+ ]:
+ """Pre-rpc interceptor for get_table
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def post_get_table(self, response: table.Table) -> table.Table:
+ """Post-rpc interceptor for get_table
+
+ DEPRECATED. Please use the `post_get_table_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableTableAdmin server but before
+ it is returned to user code. This `post_get_table` interceptor runs
+ before the `post_get_table_with_metadata` interceptor.
+ """
+ return response
+
+ def post_get_table_with_metadata(
+ self, response: table.Table, metadata: Sequence[Tuple[str, Union[str, bytes]]]
+ ) -> Tuple[table.Table, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for get_table
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableTableAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_get_table_with_metadata`
+ interceptor in new development instead of the `post_get_table` interceptor.
+ When both interceptors are used, this `post_get_table_with_metadata` interceptor runs after the
+ `post_get_table` interceptor. The (possibly modified) response returned by
+ `post_get_table` will be passed to
+ `post_get_table_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_list_authorized_views(
+ self,
+ request: bigtable_table_admin.ListAuthorizedViewsRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.ListAuthorizedViewsRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for list_authorized_views
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def post_list_authorized_views(
+ self, response: bigtable_table_admin.ListAuthorizedViewsResponse
+ ) -> bigtable_table_admin.ListAuthorizedViewsResponse:
+ """Post-rpc interceptor for list_authorized_views
+
+ DEPRECATED. Please use the `post_list_authorized_views_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableTableAdmin server but before
+ it is returned to user code. This `post_list_authorized_views` interceptor runs
+ before the `post_list_authorized_views_with_metadata` interceptor.
+ """
+ return response
+
+ def post_list_authorized_views_with_metadata(
+ self,
+ response: bigtable_table_admin.ListAuthorizedViewsResponse,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.ListAuthorizedViewsResponse,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Post-rpc interceptor for list_authorized_views
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableTableAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_list_authorized_views_with_metadata`
+ interceptor in new development instead of the `post_list_authorized_views` interceptor.
+ When both interceptors are used, this `post_list_authorized_views_with_metadata` interceptor runs after the
+ `post_list_authorized_views` interceptor. The (possibly modified) response returned by
+ `post_list_authorized_views` will be passed to
+ `post_list_authorized_views_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_list_backups(
+ self,
+ request: bigtable_table_admin.ListBackupsRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.ListBackupsRequest, Sequence[Tuple[str, Union[str, bytes]]]
+ ]:
+ """Pre-rpc interceptor for list_backups
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def post_list_backups(
+ self, response: bigtable_table_admin.ListBackupsResponse
+ ) -> bigtable_table_admin.ListBackupsResponse:
+ """Post-rpc interceptor for list_backups
+
+ DEPRECATED. Please use the `post_list_backups_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableTableAdmin server but before
+ it is returned to user code. This `post_list_backups` interceptor runs
+ before the `post_list_backups_with_metadata` interceptor.
+ """
+ return response
+
+ def post_list_backups_with_metadata(
+ self,
+ response: bigtable_table_admin.ListBackupsResponse,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.ListBackupsResponse,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Post-rpc interceptor for list_backups
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableTableAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_list_backups_with_metadata`
+ interceptor in new development instead of the `post_list_backups` interceptor.
+ When both interceptors are used, this `post_list_backups_with_metadata` interceptor runs after the
+ `post_list_backups` interceptor. The (possibly modified) response returned by
+ `post_list_backups` will be passed to
+ `post_list_backups_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_list_schema_bundles(
+ self,
+ request: bigtable_table_admin.ListSchemaBundlesRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.ListSchemaBundlesRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for list_schema_bundles
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def post_list_schema_bundles(
+ self, response: bigtable_table_admin.ListSchemaBundlesResponse
+ ) -> bigtable_table_admin.ListSchemaBundlesResponse:
+ """Post-rpc interceptor for list_schema_bundles
+
+ DEPRECATED. Please use the `post_list_schema_bundles_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableTableAdmin server but before
+ it is returned to user code. This `post_list_schema_bundles` interceptor runs
+ before the `post_list_schema_bundles_with_metadata` interceptor.
+ """
+ return response
+
+ def post_list_schema_bundles_with_metadata(
+ self,
+ response: bigtable_table_admin.ListSchemaBundlesResponse,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.ListSchemaBundlesResponse,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Post-rpc interceptor for list_schema_bundles
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableTableAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_list_schema_bundles_with_metadata`
+ interceptor in new development instead of the `post_list_schema_bundles` interceptor.
+ When both interceptors are used, this `post_list_schema_bundles_with_metadata` interceptor runs after the
+ `post_list_schema_bundles` interceptor. The (possibly modified) response returned by
+ `post_list_schema_bundles` will be passed to
+ `post_list_schema_bundles_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_list_snapshots(
+ self,
+ request: bigtable_table_admin.ListSnapshotsRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.ListSnapshotsRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for list_snapshots
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def post_list_snapshots(
+ self, response: bigtable_table_admin.ListSnapshotsResponse
+ ) -> bigtable_table_admin.ListSnapshotsResponse:
+ """Post-rpc interceptor for list_snapshots
+
+ DEPRECATED. Please use the `post_list_snapshots_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableTableAdmin server but before
+ it is returned to user code. This `post_list_snapshots` interceptor runs
+ before the `post_list_snapshots_with_metadata` interceptor.
+ """
+ return response
+
+ def post_list_snapshots_with_metadata(
+ self,
+ response: bigtable_table_admin.ListSnapshotsResponse,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.ListSnapshotsResponse,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Post-rpc interceptor for list_snapshots
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableTableAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_list_snapshots_with_metadata`
+ interceptor in new development instead of the `post_list_snapshots` interceptor.
+ When both interceptors are used, this `post_list_snapshots_with_metadata` interceptor runs after the
+ `post_list_snapshots` interceptor. The (possibly modified) response returned by
+ `post_list_snapshots` will be passed to
+ `post_list_snapshots_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_list_tables(
+ self,
+ request: bigtable_table_admin.ListTablesRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.ListTablesRequest, Sequence[Tuple[str, Union[str, bytes]]]
+ ]:
+ """Pre-rpc interceptor for list_tables
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def post_list_tables(
+ self, response: bigtable_table_admin.ListTablesResponse
+ ) -> bigtable_table_admin.ListTablesResponse:
+ """Post-rpc interceptor for list_tables
+
+ DEPRECATED. Please use the `post_list_tables_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableTableAdmin server but before
+ it is returned to user code. This `post_list_tables` interceptor runs
+ before the `post_list_tables_with_metadata` interceptor.
+ """
+ return response
+
+ def post_list_tables_with_metadata(
+ self,
+ response: bigtable_table_admin.ListTablesResponse,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.ListTablesResponse, Sequence[Tuple[str, Union[str, bytes]]]
+ ]:
+ """Post-rpc interceptor for list_tables
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableTableAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_list_tables_with_metadata`
+ interceptor in new development instead of the `post_list_tables` interceptor.
+ When both interceptors are used, this `post_list_tables_with_metadata` interceptor runs after the
+ `post_list_tables` interceptor. The (possibly modified) response returned by
+ `post_list_tables` will be passed to
+ `post_list_tables_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_modify_column_families(
+ self,
+ request: bigtable_table_admin.ModifyColumnFamiliesRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.ModifyColumnFamiliesRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for modify_column_families
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def post_modify_column_families(self, response: table.Table) -> table.Table:
+ """Post-rpc interceptor for modify_column_families
+
+ DEPRECATED. Please use the `post_modify_column_families_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableTableAdmin server but before
+ it is returned to user code. This `post_modify_column_families` interceptor runs
+ before the `post_modify_column_families_with_metadata` interceptor.
+ """
+ return response
+
+ def post_modify_column_families_with_metadata(
+ self, response: table.Table, metadata: Sequence[Tuple[str, Union[str, bytes]]]
+ ) -> Tuple[table.Table, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for modify_column_families
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableTableAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_modify_column_families_with_metadata`
+ interceptor in new development instead of the `post_modify_column_families` interceptor.
+ When both interceptors are used, this `post_modify_column_families_with_metadata` interceptor runs after the
+ `post_modify_column_families` interceptor. The (possibly modified) response returned by
+ `post_modify_column_families` will be passed to
+ `post_modify_column_families_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_restore_table(
+ self,
+ request: bigtable_table_admin.RestoreTableRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.RestoreTableRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for restore_table
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def post_restore_table(
+ self, response: operations_pb2.Operation
+ ) -> operations_pb2.Operation:
+ """Post-rpc interceptor for restore_table
+
+ DEPRECATED. Please use the `post_restore_table_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableTableAdmin server but before
+ it is returned to user code. This `post_restore_table` interceptor runs
+ before the `post_restore_table_with_metadata` interceptor.
+ """
+ return response
+
+ def post_restore_table_with_metadata(
+ self,
+ response: operations_pb2.Operation,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for restore_table
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableTableAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_restore_table_with_metadata`
+ interceptor in new development instead of the `post_restore_table` interceptor.
+ When both interceptors are used, this `post_restore_table_with_metadata` interceptor runs after the
+ `post_restore_table` interceptor. The (possibly modified) response returned by
+ `post_restore_table` will be passed to
+ `post_restore_table_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_set_iam_policy(
+ self,
+ request: iam_policy_pb2.SetIamPolicyRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ iam_policy_pb2.SetIamPolicyRequest, Sequence[Tuple[str, Union[str, bytes]]]
+ ]:
+ """Pre-rpc interceptor for set_iam_policy
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def post_set_iam_policy(self, response: policy_pb2.Policy) -> policy_pb2.Policy:
+ """Post-rpc interceptor for set_iam_policy
+
+ DEPRECATED. Please use the `post_set_iam_policy_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableTableAdmin server but before
+ it is returned to user code. This `post_set_iam_policy` interceptor runs
+ before the `post_set_iam_policy_with_metadata` interceptor.
+ """
+ return response
+
+ def post_set_iam_policy_with_metadata(
+ self,
+ response: policy_pb2.Policy,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[policy_pb2.Policy, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for set_iam_policy
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableTableAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_set_iam_policy_with_metadata`
+ interceptor in new development instead of the `post_set_iam_policy` interceptor.
+ When both interceptors are used, this `post_set_iam_policy_with_metadata` interceptor runs after the
+ `post_set_iam_policy` interceptor. The (possibly modified) response returned by
+ `post_set_iam_policy` will be passed to
+ `post_set_iam_policy_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_snapshot_table(
+ self,
+ request: bigtable_table_admin.SnapshotTableRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.SnapshotTableRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for snapshot_table
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def post_snapshot_table(
+ self, response: operations_pb2.Operation
+ ) -> operations_pb2.Operation:
+ """Post-rpc interceptor for snapshot_table
+
+ DEPRECATED. Please use the `post_snapshot_table_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableTableAdmin server but before
+ it is returned to user code. This `post_snapshot_table` interceptor runs
+ before the `post_snapshot_table_with_metadata` interceptor.
+ """
+ return response
+
+ def post_snapshot_table_with_metadata(
+ self,
+ response: operations_pb2.Operation,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for snapshot_table
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableTableAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_snapshot_table_with_metadata`
+ interceptor in new development instead of the `post_snapshot_table` interceptor.
+ When both interceptors are used, this `post_snapshot_table_with_metadata` interceptor runs after the
+ `post_snapshot_table` interceptor. The (possibly modified) response returned by
+ `post_snapshot_table` will be passed to
+ `post_snapshot_table_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_test_iam_permissions(
+ self,
+ request: iam_policy_pb2.TestIamPermissionsRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ iam_policy_pb2.TestIamPermissionsRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for test_iam_permissions
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def post_test_iam_permissions(
+ self, response: iam_policy_pb2.TestIamPermissionsResponse
+ ) -> iam_policy_pb2.TestIamPermissionsResponse:
+ """Post-rpc interceptor for test_iam_permissions
+
+ DEPRECATED. Please use the `post_test_iam_permissions_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableTableAdmin server but before
+ it is returned to user code. This `post_test_iam_permissions` interceptor runs
+ before the `post_test_iam_permissions_with_metadata` interceptor.
+ """
+ return response
+
+ def post_test_iam_permissions_with_metadata(
+ self,
+ response: iam_policy_pb2.TestIamPermissionsResponse,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ iam_policy_pb2.TestIamPermissionsResponse,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Post-rpc interceptor for test_iam_permissions
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableTableAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_test_iam_permissions_with_metadata`
+ interceptor in new development instead of the `post_test_iam_permissions` interceptor.
+ When both interceptors are used, this `post_test_iam_permissions_with_metadata` interceptor runs after the
+ `post_test_iam_permissions` interceptor. The (possibly modified) response returned by
+ `post_test_iam_permissions` will be passed to
+ `post_test_iam_permissions_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_undelete_table(
+ self,
+ request: bigtable_table_admin.UndeleteTableRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.UndeleteTableRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for undelete_table
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def post_undelete_table(
+ self, response: operations_pb2.Operation
+ ) -> operations_pb2.Operation:
+ """Post-rpc interceptor for undelete_table
+
+ DEPRECATED. Please use the `post_undelete_table_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableTableAdmin server but before
+ it is returned to user code. This `post_undelete_table` interceptor runs
+ before the `post_undelete_table_with_metadata` interceptor.
+ """
+ return response
+
+ def post_undelete_table_with_metadata(
+ self,
+ response: operations_pb2.Operation,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for undelete_table
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableTableAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_undelete_table_with_metadata`
+ interceptor in new development instead of the `post_undelete_table` interceptor.
+ When both interceptors are used, this `post_undelete_table_with_metadata` interceptor runs after the
+ `post_undelete_table` interceptor. The (possibly modified) response returned by
+ `post_undelete_table` will be passed to
+ `post_undelete_table_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_update_authorized_view(
+ self,
+ request: bigtable_table_admin.UpdateAuthorizedViewRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.UpdateAuthorizedViewRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for update_authorized_view
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def post_update_authorized_view(
+ self, response: operations_pb2.Operation
+ ) -> operations_pb2.Operation:
+ """Post-rpc interceptor for update_authorized_view
+
+ DEPRECATED. Please use the `post_update_authorized_view_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableTableAdmin server but before
+ it is returned to user code. This `post_update_authorized_view` interceptor runs
+ before the `post_update_authorized_view_with_metadata` interceptor.
+ """
+ return response
+
+ def post_update_authorized_view_with_metadata(
+ self,
+ response: operations_pb2.Operation,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for update_authorized_view
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableTableAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_update_authorized_view_with_metadata`
+ interceptor in new development instead of the `post_update_authorized_view` interceptor.
+ When both interceptors are used, this `post_update_authorized_view_with_metadata` interceptor runs after the
+ `post_update_authorized_view` interceptor. The (possibly modified) response returned by
+ `post_update_authorized_view` will be passed to
+ `post_update_authorized_view_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_update_backup(
+ self,
+ request: bigtable_table_admin.UpdateBackupRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.UpdateBackupRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for update_backup
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def post_update_backup(self, response: table.Backup) -> table.Backup:
+ """Post-rpc interceptor for update_backup
+
+ DEPRECATED. Please use the `post_update_backup_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableTableAdmin server but before
+ it is returned to user code. This `post_update_backup` interceptor runs
+ before the `post_update_backup_with_metadata` interceptor.
+ """
+ return response
+
+ def post_update_backup_with_metadata(
+ self, response: table.Backup, metadata: Sequence[Tuple[str, Union[str, bytes]]]
+ ) -> Tuple[table.Backup, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for update_backup
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableTableAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_update_backup_with_metadata`
+ interceptor in new development instead of the `post_update_backup` interceptor.
+ When both interceptors are used, this `post_update_backup_with_metadata` interceptor runs after the
+ `post_update_backup` interceptor. The (possibly modified) response returned by
+ `post_update_backup` will be passed to
+ `post_update_backup_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_update_schema_bundle(
+ self,
+ request: bigtable_table_admin.UpdateSchemaBundleRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.UpdateSchemaBundleRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for update_schema_bundle
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def post_update_schema_bundle(
+ self, response: operations_pb2.Operation
+ ) -> operations_pb2.Operation:
+ """Post-rpc interceptor for update_schema_bundle
+
+ DEPRECATED. Please use the `post_update_schema_bundle_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableTableAdmin server but before
+ it is returned to user code. This `post_update_schema_bundle` interceptor runs
+ before the `post_update_schema_bundle_with_metadata` interceptor.
+ """
+ return response
+
+ def post_update_schema_bundle_with_metadata(
+ self,
+ response: operations_pb2.Operation,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for update_schema_bundle
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableTableAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_update_schema_bundle_with_metadata`
+ interceptor in new development instead of the `post_update_schema_bundle` interceptor.
+ When both interceptors are used, this `post_update_schema_bundle_with_metadata` interceptor runs after the
+ `post_update_schema_bundle` interceptor. The (possibly modified) response returned by
+ `post_update_schema_bundle` will be passed to
+ `post_update_schema_bundle_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_update_table(
+ self,
+ request: bigtable_table_admin.UpdateTableRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable_table_admin.UpdateTableRequest, Sequence[Tuple[str, Union[str, bytes]]]
+ ]:
+ """Pre-rpc interceptor for update_table
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the BigtableTableAdmin server.
+ """
+ return request, metadata
+
+ def post_update_table(
+ self, response: operations_pb2.Operation
+ ) -> operations_pb2.Operation:
+ """Post-rpc interceptor for update_table
+
+ DEPRECATED. Please use the `post_update_table_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the BigtableTableAdmin server but before
+ it is returned to user code. This `post_update_table` interceptor runs
+ before the `post_update_table_with_metadata` interceptor.
+ """
+ return response
+
+ def post_update_table_with_metadata(
+ self,
+ response: operations_pb2.Operation,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for update_table
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the BigtableTableAdmin server but before it is returned to user code.
+
+ We recommend only using this `post_update_table_with_metadata`
+ interceptor in new development instead of the `post_update_table` interceptor.
+ When both interceptors are used, this `post_update_table_with_metadata` interceptor runs after the
+ `post_update_table` interceptor. The (possibly modified) response returned by
+ `post_update_table` will be passed to
+ `post_update_table_with_metadata`.
+ """
+ return response, metadata
+
+
+@dataclasses.dataclass
+class BigtableTableAdminRestStub:
+ _session: AuthorizedSession
+ _host: str
+ _interceptor: BigtableTableAdminRestInterceptor
+
+
+class BigtableTableAdminRestTransport(_BaseBigtableTableAdminRestTransport):
+ """REST backend synchronous transport for BigtableTableAdmin.
+
+ Service for creating, configuring, and deleting Cloud
+ Bigtable tables.
+
+ Provides access to the table schemas only, not the data stored
+ within the tables.
+
+ This class defines the same methods as the primary client, so the
+ primary client can load the underlying transport implementation
+ and call it.
+
+ It sends JSON representations of protocol buffers over HTTP/1.1
+ """
+
+ def __init__(
+ self,
+ *,
+ host: str = "bigtableadmin.googleapis.com",
+ credentials: Optional[ga_credentials.Credentials] = None,
+ credentials_file: Optional[str] = None,
+ scopes: Optional[Sequence[str]] = None,
+ client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None,
+ quota_project_id: Optional[str] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ always_use_jwt_access: Optional[bool] = False,
+ url_scheme: str = "https",
+ interceptor: Optional[BigtableTableAdminRestInterceptor] = None,
+ api_audience: Optional[str] = None,
+ ) -> None:
+ """Instantiate the transport.
+
+ Args:
+ host (Optional[str]):
+ The hostname to connect to (default: 'bigtableadmin.googleapis.com').
+ credentials (Optional[google.auth.credentials.Credentials]): The
+ authorization credentials to attach to requests. These
+ credentials identify the application to the service; if none
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+
+ credentials_file (Optional[str]): Deprecated. A file with credentials that can
+ be loaded with :func:`google.auth.load_credentials_from_file`.
+ This argument is ignored if ``channel`` is provided. This argument will be
+ removed in the next major version of this library.
+ scopes (Optional(Sequence[str])): A list of scopes. This argument is
+ ignored if ``channel`` is provided.
+ client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client
+ certificate to configure mutual TLS HTTP channel. It is ignored
+ if ``channel`` is provided.
+ quota_project_id (Optional[str]): An optional project to use for billing
+ and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you are developing
+ your own client library.
+ always_use_jwt_access (Optional[bool]): Whether self signed JWT should
+ be used for service account credentials.
+ url_scheme: the protocol scheme for the API endpoint. Normally
+ "https", but for testing or local servers,
+ "http" can be specified.
+ """
+ # Run the base constructor
+ # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc.
+ # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the
+ # credentials object
+ super().__init__(
+ host=host,
+ credentials=credentials,
+ client_info=client_info,
+ always_use_jwt_access=always_use_jwt_access,
+ url_scheme=url_scheme,
+ api_audience=api_audience,
+ )
+ self._session = AuthorizedSession(
+ self._credentials, default_host=self.DEFAULT_HOST
+ )
+ self._operations_client: Optional[operations_v1.AbstractOperationsClient] = None
+ if client_cert_source_for_mtls:
+ self._session.configure_mtls_channel(client_cert_source_for_mtls)
+ self._interceptor = interceptor or BigtableTableAdminRestInterceptor()
+ self._prep_wrapped_messages(client_info)
+
+ @property
+ def operations_client(self) -> operations_v1.AbstractOperationsClient:
+ """Create the client designed to process long-running operations.
+
+ This property caches on the instance; repeated calls return the same
+ client.
+ """
+ # Only create a new client if we do not already have one.
+ if self._operations_client is None:
+ http_options: Dict[str, List[Dict[str, str]]] = {
+ "google.longrunning.Operations.CancelOperation": [
+ {
+ "method": "post",
+ "uri": "/v2/{name=operations/**}:cancel",
+ },
+ ],
+ "google.longrunning.Operations.DeleteOperation": [
+ {
+ "method": "delete",
+ "uri": "/v2/{name=operations/**}",
+ },
+ ],
+ "google.longrunning.Operations.GetOperation": [
+ {
+ "method": "get",
+ "uri": "/v2/{name=operations/**}",
+ },
+ ],
+ "google.longrunning.Operations.ListOperations": [
+ {
+ "method": "get",
+ "uri": "/v2/{name=operations/projects/**}/operations",
+ },
+ ],
+ }
+
+ rest_transport = operations_v1.OperationsRestTransport(
+ host=self._host,
+ # use the credentials which are saved
+ credentials=self._credentials,
+ scopes=self._scopes,
+ http_options=http_options,
+ path_prefix="v2",
+ )
+
+ self._operations_client = operations_v1.AbstractOperationsClient(
+ transport=rest_transport
+ )
+
+ # Return the client from cache.
+ return self._operations_client
+
+ class _CheckConsistency(
+ _BaseBigtableTableAdminRestTransport._BaseCheckConsistency,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.CheckConsistency")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.CheckConsistencyRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> bigtable_table_admin.CheckConsistencyResponse:
+ r"""Call the check consistency method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.CheckConsistencyRequest):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency][google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency]
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.bigtable_table_admin.CheckConsistencyResponse:
+ Response message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency][google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency]
+
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseCheckConsistency._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_check_consistency(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseCheckConsistency._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableTableAdminRestTransport._BaseCheckConsistency._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseCheckConsistency._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.CheckConsistency",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "CheckConsistency",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableTableAdminRestTransport._CheckConsistency._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = bigtable_table_admin.CheckConsistencyResponse()
+ pb_resp = bigtable_table_admin.CheckConsistencyResponse.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_check_consistency(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_check_consistency_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = (
+ bigtable_table_admin.CheckConsistencyResponse.to_json(response)
+ )
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BaseBigtableTableAdminClient.check_consistency",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "CheckConsistency",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _CopyBackup(
+ _BaseBigtableTableAdminRestTransport._BaseCopyBackup, BigtableTableAdminRestStub
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.CopyBackup")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.CopyBackupRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operations_pb2.Operation:
+ r"""Call the copy backup method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.CopyBackupRequest):
+ The request object. The request for
+ [CopyBackup][google.bigtable.admin.v2.BigtableTableAdmin.CopyBackup].
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.operations_pb2.Operation:
+ This resource represents a
+ long-running operation that is the
+ result of a network API call.
+
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseCopyBackup._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_copy_backup(request, metadata)
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseCopyBackup._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableTableAdminRestTransport._BaseCopyBackup._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseCopyBackup._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.CopyBackup",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "CopyBackup",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableTableAdminRestTransport._CopyBackup._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = operations_pb2.Operation()
+ json_format.Parse(response.content, resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_copy_backup(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_copy_backup_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = json_format.MessageToJson(resp)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BaseBigtableTableAdminClient.copy_backup",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "CopyBackup",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _CreateAuthorizedView(
+ _BaseBigtableTableAdminRestTransport._BaseCreateAuthorizedView,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.CreateAuthorizedView")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.CreateAuthorizedViewRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operations_pb2.Operation:
+ r"""Call the create authorized view method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.CreateAuthorizedViewRequest):
+ The request object. The request for
+ [CreateAuthorizedView][google.bigtable.admin.v2.BigtableTableAdmin.CreateAuthorizedView]
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.operations_pb2.Operation:
+ This resource represents a
+ long-running operation that is the
+ result of a network API call.
+
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseCreateAuthorizedView._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_create_authorized_view(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseCreateAuthorizedView._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableTableAdminRestTransport._BaseCreateAuthorizedView._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseCreateAuthorizedView._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.CreateAuthorizedView",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "CreateAuthorizedView",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = (
+ BigtableTableAdminRestTransport._CreateAuthorizedView._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = operations_pb2.Operation()
+ json_format.Parse(response.content, resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_create_authorized_view(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_create_authorized_view_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = json_format.MessageToJson(resp)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BaseBigtableTableAdminClient.create_authorized_view",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "CreateAuthorizedView",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _CreateBackup(
+ _BaseBigtableTableAdminRestTransport._BaseCreateBackup,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.CreateBackup")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.CreateBackupRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operations_pb2.Operation:
+ r"""Call the create backup method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.CreateBackupRequest):
+ The request object. The request for
+ [CreateBackup][google.bigtable.admin.v2.BigtableTableAdmin.CreateBackup].
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.operations_pb2.Operation:
+ This resource represents a
+ long-running operation that is the
+ result of a network API call.
+
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseCreateBackup._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_create_backup(request, metadata)
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseCreateBackup._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableTableAdminRestTransport._BaseCreateBackup._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseCreateBackup._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.CreateBackup",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "CreateBackup",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableTableAdminRestTransport._CreateBackup._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = operations_pb2.Operation()
+ json_format.Parse(response.content, resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_create_backup(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_create_backup_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = json_format.MessageToJson(resp)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BaseBigtableTableAdminClient.create_backup",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "CreateBackup",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _CreateSchemaBundle(
+ _BaseBigtableTableAdminRestTransport._BaseCreateSchemaBundle,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.CreateSchemaBundle")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.CreateSchemaBundleRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operations_pb2.Operation:
+ r"""Call the create schema bundle method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.CreateSchemaBundleRequest):
+ The request object. The request for
+ [CreateSchemaBundle][google.bigtable.admin.v2.BigtableTableAdmin.CreateSchemaBundle].
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.operations_pb2.Operation:
+ This resource represents a
+ long-running operation that is the
+ result of a network API call.
+
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseCreateSchemaBundle._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_create_schema_bundle(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseCreateSchemaBundle._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableTableAdminRestTransport._BaseCreateSchemaBundle._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseCreateSchemaBundle._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.CreateSchemaBundle",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "CreateSchemaBundle",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = (
+ BigtableTableAdminRestTransport._CreateSchemaBundle._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = operations_pb2.Operation()
+ json_format.Parse(response.content, resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_create_schema_bundle(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_create_schema_bundle_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = json_format.MessageToJson(resp)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BaseBigtableTableAdminClient.create_schema_bundle",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "CreateSchemaBundle",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _CreateTable(
+ _BaseBigtableTableAdminRestTransport._BaseCreateTable,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.CreateTable")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.CreateTableRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> gba_table.Table:
+ r"""Call the create table method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.CreateTableRequest):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.CreateTable][google.bigtable.admin.v2.BigtableTableAdmin.CreateTable]
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.gba_table.Table:
+ A collection of user data indexed by
+ row, column, and timestamp. Each table
+ is served using the resources of its
+ parent cluster.
+
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseCreateTable._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_create_table(request, metadata)
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseCreateTable._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableTableAdminRestTransport._BaseCreateTable._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseCreateTable._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.CreateTable",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "CreateTable",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableTableAdminRestTransport._CreateTable._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = gba_table.Table()
+ pb_resp = gba_table.Table.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_create_table(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_create_table_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = gba_table.Table.to_json(response)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BaseBigtableTableAdminClient.create_table",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "CreateTable",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _CreateTableFromSnapshot(
+ _BaseBigtableTableAdminRestTransport._BaseCreateTableFromSnapshot,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.CreateTableFromSnapshot")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.CreateTableFromSnapshotRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operations_pb2.Operation:
+ r"""Call the create table from
+ snapshot method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.CreateTableFromSnapshotRequest):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.CreateTableFromSnapshot][google.bigtable.admin.v2.BigtableTableAdmin.CreateTableFromSnapshot]
+
+ Note: This is a private alpha release of Cloud Bigtable
+ snapshots. This feature is not currently available to
+ most Cloud Bigtable customers. This feature might be
+ changed in backward-incompatible ways and is not
+ recommended for production use. It is not subject to any
+ SLA or deprecation policy.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.operations_pb2.Operation:
+ This resource represents a
+ long-running operation that is the
+ result of a network API call.
+
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseCreateTableFromSnapshot._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_create_table_from_snapshot(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseCreateTableFromSnapshot._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableTableAdminRestTransport._BaseCreateTableFromSnapshot._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseCreateTableFromSnapshot._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.CreateTableFromSnapshot",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "CreateTableFromSnapshot",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = (
+ BigtableTableAdminRestTransport._CreateTableFromSnapshot._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = operations_pb2.Operation()
+ json_format.Parse(response.content, resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_create_table_from_snapshot(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_create_table_from_snapshot_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = json_format.MessageToJson(resp)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BaseBigtableTableAdminClient.create_table_from_snapshot",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "CreateTableFromSnapshot",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _DeleteAuthorizedView(
+ _BaseBigtableTableAdminRestTransport._BaseDeleteAuthorizedView,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.DeleteAuthorizedView")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.DeleteAuthorizedViewRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ):
+ r"""Call the delete authorized view method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.DeleteAuthorizedViewRequest):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.DeleteAuthorizedView][google.bigtable.admin.v2.BigtableTableAdmin.DeleteAuthorizedView]
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseDeleteAuthorizedView._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_delete_authorized_view(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseDeleteAuthorizedView._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseDeleteAuthorizedView._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.DeleteAuthorizedView",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "DeleteAuthorizedView",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = (
+ BigtableTableAdminRestTransport._DeleteAuthorizedView._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ class _DeleteBackup(
+ _BaseBigtableTableAdminRestTransport._BaseDeleteBackup,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.DeleteBackup")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.DeleteBackupRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ):
+ r"""Call the delete backup method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.DeleteBackupRequest):
+ The request object. The request for
+ [DeleteBackup][google.bigtable.admin.v2.BigtableTableAdmin.DeleteBackup].
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseDeleteBackup._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_delete_backup(request, metadata)
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseDeleteBackup._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseDeleteBackup._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.DeleteBackup",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "DeleteBackup",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableTableAdminRestTransport._DeleteBackup._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ class _DeleteSchemaBundle(
+ _BaseBigtableTableAdminRestTransport._BaseDeleteSchemaBundle,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.DeleteSchemaBundle")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.DeleteSchemaBundleRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ):
+ r"""Call the delete schema bundle method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.DeleteSchemaBundleRequest):
+ The request object. The request for
+ [DeleteSchemaBundle][google.bigtable.admin.v2.BigtableTableAdmin.DeleteSchemaBundle].
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseDeleteSchemaBundle._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_delete_schema_bundle(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseDeleteSchemaBundle._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseDeleteSchemaBundle._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.DeleteSchemaBundle",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "DeleteSchemaBundle",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = (
+ BigtableTableAdminRestTransport._DeleteSchemaBundle._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ class _DeleteSnapshot(
+ _BaseBigtableTableAdminRestTransport._BaseDeleteSnapshot,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.DeleteSnapshot")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.DeleteSnapshotRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ):
+ r"""Call the delete snapshot method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.DeleteSnapshotRequest):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.DeleteSnapshot][google.bigtable.admin.v2.BigtableTableAdmin.DeleteSnapshot]
+
+ Note: This is a private alpha release of Cloud Bigtable
+ snapshots. This feature is not currently available to
+ most Cloud Bigtable customers. This feature might be
+ changed in backward-incompatible ways and is not
+ recommended for production use. It is not subject to any
+ SLA or deprecation policy.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseDeleteSnapshot._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_delete_snapshot(request, metadata)
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseDeleteSnapshot._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseDeleteSnapshot._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.DeleteSnapshot",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "DeleteSnapshot",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableTableAdminRestTransport._DeleteSnapshot._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ class _DeleteTable(
+ _BaseBigtableTableAdminRestTransport._BaseDeleteTable,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.DeleteTable")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.DeleteTableRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ):
+ r"""Call the delete table method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.DeleteTableRequest):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.DeleteTable][google.bigtable.admin.v2.BigtableTableAdmin.DeleteTable]
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseDeleteTable._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_delete_table(request, metadata)
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseDeleteTable._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseDeleteTable._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.DeleteTable",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "DeleteTable",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableTableAdminRestTransport._DeleteTable._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ class _DropRowRange(
+ _BaseBigtableTableAdminRestTransport._BaseDropRowRange,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.DropRowRange")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.DropRowRangeRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ):
+ r"""Call the drop row range method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.DropRowRangeRequest):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.DropRowRange][google.bigtable.admin.v2.BigtableTableAdmin.DropRowRange]
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseDropRowRange._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_drop_row_range(request, metadata)
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseDropRowRange._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableTableAdminRestTransport._BaseDropRowRange._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseDropRowRange._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.DropRowRange",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "DropRowRange",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableTableAdminRestTransport._DropRowRange._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ class _GenerateConsistencyToken(
+ _BaseBigtableTableAdminRestTransport._BaseGenerateConsistencyToken,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.GenerateConsistencyToken")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.GenerateConsistencyTokenRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> bigtable_table_admin.GenerateConsistencyTokenResponse:
+ r"""Call the generate consistency
+ token method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.GenerateConsistencyTokenRequest):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken][google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken]
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.bigtable_table_admin.GenerateConsistencyTokenResponse:
+ Response message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken][google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken]
+
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseGenerateConsistencyToken._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_generate_consistency_token(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseGenerateConsistencyToken._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableTableAdminRestTransport._BaseGenerateConsistencyToken._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseGenerateConsistencyToken._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.GenerateConsistencyToken",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "GenerateConsistencyToken",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = (
+ BigtableTableAdminRestTransport._GenerateConsistencyToken._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = bigtable_table_admin.GenerateConsistencyTokenResponse()
+ pb_resp = bigtable_table_admin.GenerateConsistencyTokenResponse.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_generate_consistency_token(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_generate_consistency_token_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = (
+ bigtable_table_admin.GenerateConsistencyTokenResponse.to_json(
+ response
+ )
+ )
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BaseBigtableTableAdminClient.generate_consistency_token",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "GenerateConsistencyToken",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _GetAuthorizedView(
+ _BaseBigtableTableAdminRestTransport._BaseGetAuthorizedView,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.GetAuthorizedView")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.GetAuthorizedViewRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> table.AuthorizedView:
+ r"""Call the get authorized view method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.GetAuthorizedViewRequest):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.GetAuthorizedView][google.bigtable.admin.v2.BigtableTableAdmin.GetAuthorizedView]
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.table.AuthorizedView:
+ AuthorizedViews represent subsets of
+ a particular Cloud Bigtable table. Users
+ can configure access to each Authorized
+ View independently from the table and
+ use the existing Data APIs to access the
+ subset of data.
+
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseGetAuthorizedView._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_get_authorized_view(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseGetAuthorizedView._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseGetAuthorizedView._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.GetAuthorizedView",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "GetAuthorizedView",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableTableAdminRestTransport._GetAuthorizedView._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = table.AuthorizedView()
+ pb_resp = table.AuthorizedView.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_get_authorized_view(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_get_authorized_view_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = table.AuthorizedView.to_json(response)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BaseBigtableTableAdminClient.get_authorized_view",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "GetAuthorizedView",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _GetBackup(
+ _BaseBigtableTableAdminRestTransport._BaseGetBackup, BigtableTableAdminRestStub
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.GetBackup")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.GetBackupRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> table.Backup:
+ r"""Call the get backup method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.GetBackupRequest):
+ The request object. The request for
+ [GetBackup][google.bigtable.admin.v2.BigtableTableAdmin.GetBackup].
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.table.Backup:
+ A backup of a Cloud Bigtable table.
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseGetBackup._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_get_backup(request, metadata)
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseGetBackup._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseGetBackup._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.GetBackup",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "GetBackup",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableTableAdminRestTransport._GetBackup._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = table.Backup()
+ pb_resp = table.Backup.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_get_backup(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_get_backup_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = table.Backup.to_json(response)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BaseBigtableTableAdminClient.get_backup",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "GetBackup",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _GetIamPolicy(
+ _BaseBigtableTableAdminRestTransport._BaseGetIamPolicy,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.GetIamPolicy")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: iam_policy_pb2.GetIamPolicyRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> policy_pb2.Policy:
+ r"""Call the get iam policy method over HTTP.
+
+ Args:
+ request (~.iam_policy_pb2.GetIamPolicyRequest):
+ The request object. Request message for ``GetIamPolicy`` method.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.policy_pb2.Policy:
+ An Identity and Access Management (IAM) policy, which
+ specifies access controls for Google Cloud resources.
+
+ A ``Policy`` is a collection of ``bindings``. A
+ ``binding`` binds one or more ``members``, or
+ principals, to a single ``role``. Principals can be user
+ accounts, service accounts, Google groups, and domains
+ (such as G Suite). A ``role`` is a named list of
+ permissions; each ``role`` can be an IAM predefined role
+ or a user-created custom role.
+
+ For some types of Google Cloud resources, a ``binding``
+ can also specify a ``condition``, which is a logical
+ expression that allows access to a resource only if the
+ expression evaluates to ``true``. A condition can add
+ constraints based on attributes of the request, the
+ resource, or both. To learn which resources support
+ conditions in their IAM policies, see the `IAM
+ documentation `__.
+
+ **JSON example:**
+
+ ::
+
+ {
+ "bindings": [
+ {
+ "role": "roles/resourcemanager.organizationAdmin",
+ "members": [
+ "user:mike@example.com",
+ "group:admins@example.com",
+ "domain:google.com",
+ "serviceAccount:my-project-id@appspot.gserviceaccount.com"
+ ]
+ },
+ {
+ "role": "roles/resourcemanager.organizationViewer",
+ "members": [
+ "user:eve@example.com"
+ ],
+ "condition": {
+ "title": "expirable access",
+ "description": "Does not grant access after Sep 2020",
+ "expression": "request.time <
+ timestamp('2020-10-01T00:00:00.000Z')",
+ }
+ }
+ ],
+ "etag": "BwWWja0YfJA=",
+ "version": 3
+ }
+
+ **YAML example:**
+
+ ::
+
+ bindings:
+ - members:
+ - user:mike@example.com
+ - group:admins@example.com
+ - domain:google.com
+ - serviceAccount:my-project-id@appspot.gserviceaccount.com
+ role: roles/resourcemanager.organizationAdmin
+ - members:
+ - user:eve@example.com
+ role: roles/resourcemanager.organizationViewer
+ condition:
+ title: expirable access
+ description: Does not grant access after Sep 2020
+ expression: request.time < timestamp('2020-10-01T00:00:00.000Z')
+ etag: BwWWja0YfJA=
+ version: 3
+
+ For a description of IAM and its features, see the `IAM
+ documentation `__.
+
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseGetIamPolicy._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_get_iam_policy(request, metadata)
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseGetIamPolicy._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableTableAdminRestTransport._BaseGetIamPolicy._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseGetIamPolicy._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.GetIamPolicy",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "GetIamPolicy",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableTableAdminRestTransport._GetIamPolicy._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = policy_pb2.Policy()
+ pb_resp = resp
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_get_iam_policy(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_get_iam_policy_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = json_format.MessageToJson(resp)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BaseBigtableTableAdminClient.get_iam_policy",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "GetIamPolicy",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _GetSchemaBundle(
+ _BaseBigtableTableAdminRestTransport._BaseGetSchemaBundle,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.GetSchemaBundle")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.GetSchemaBundleRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> table.SchemaBundle:
+ r"""Call the get schema bundle method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.GetSchemaBundleRequest):
+ The request object. The request for
+ [GetSchemaBundle][google.bigtable.admin.v2.BigtableTableAdmin.GetSchemaBundle].
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.table.SchemaBundle:
+ A named collection of related
+ schemas.
+
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseGetSchemaBundle._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_get_schema_bundle(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseGetSchemaBundle._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseGetSchemaBundle._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.GetSchemaBundle",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "GetSchemaBundle",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableTableAdminRestTransport._GetSchemaBundle._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = table.SchemaBundle()
+ pb_resp = table.SchemaBundle.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_get_schema_bundle(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_get_schema_bundle_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = table.SchemaBundle.to_json(response)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BaseBigtableTableAdminClient.get_schema_bundle",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "GetSchemaBundle",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _GetSnapshot(
+ _BaseBigtableTableAdminRestTransport._BaseGetSnapshot,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.GetSnapshot")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.GetSnapshotRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> table.Snapshot:
+ r"""Call the get snapshot method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.GetSnapshotRequest):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.GetSnapshot][google.bigtable.admin.v2.BigtableTableAdmin.GetSnapshot]
+
+ Note: This is a private alpha release of Cloud Bigtable
+ snapshots. This feature is not currently available to
+ most Cloud Bigtable customers. This feature might be
+ changed in backward-incompatible ways and is not
+ recommended for production use. It is not subject to any
+ SLA or deprecation policy.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.table.Snapshot:
+ A snapshot of a table at a particular
+ time. A snapshot can be used as a
+ checkpoint for data restoration or a
+ data source for a new table.
+
+ Note: This is a private alpha release of
+ Cloud Bigtable snapshots. This feature
+ is not currently available to most Cloud
+ Bigtable customers. This feature might
+ be changed in backward-incompatible ways
+ and is not recommended for production
+ use. It is not subject to any SLA or
+ deprecation policy.
+
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseGetSnapshot._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_get_snapshot(request, metadata)
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseGetSnapshot._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseGetSnapshot._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.GetSnapshot",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "GetSnapshot",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableTableAdminRestTransport._GetSnapshot._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = table.Snapshot()
+ pb_resp = table.Snapshot.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_get_snapshot(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_get_snapshot_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = table.Snapshot.to_json(response)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BaseBigtableTableAdminClient.get_snapshot",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "GetSnapshot",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _GetTable(
+ _BaseBigtableTableAdminRestTransport._BaseGetTable, BigtableTableAdminRestStub
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.GetTable")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.GetTableRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> table.Table:
+ r"""Call the get table method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.GetTableRequest):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.GetTable][google.bigtable.admin.v2.BigtableTableAdmin.GetTable]
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.table.Table:
+ A collection of user data indexed by
+ row, column, and timestamp. Each table
+ is served using the resources of its
+ parent cluster.
+
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseGetTable._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_get_table(request, metadata)
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseGetTable._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseGetTable._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.GetTable",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "GetTable",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableTableAdminRestTransport._GetTable._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = table.Table()
+ pb_resp = table.Table.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_get_table(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_get_table_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = table.Table.to_json(response)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BaseBigtableTableAdminClient.get_table",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "GetTable",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _ListAuthorizedViews(
+ _BaseBigtableTableAdminRestTransport._BaseListAuthorizedViews,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.ListAuthorizedViews")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.ListAuthorizedViewsRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> bigtable_table_admin.ListAuthorizedViewsResponse:
+ r"""Call the list authorized views method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.ListAuthorizedViewsRequest):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.ListAuthorizedViews][google.bigtable.admin.v2.BigtableTableAdmin.ListAuthorizedViews]
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.bigtable_table_admin.ListAuthorizedViewsResponse:
+ Response message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.ListAuthorizedViews][google.bigtable.admin.v2.BigtableTableAdmin.ListAuthorizedViews]
+
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseListAuthorizedViews._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_list_authorized_views(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseListAuthorizedViews._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseListAuthorizedViews._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.ListAuthorizedViews",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "ListAuthorizedViews",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = (
+ BigtableTableAdminRestTransport._ListAuthorizedViews._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = bigtable_table_admin.ListAuthorizedViewsResponse()
+ pb_resp = bigtable_table_admin.ListAuthorizedViewsResponse.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_list_authorized_views(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_list_authorized_views_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = (
+ bigtable_table_admin.ListAuthorizedViewsResponse.to_json(
+ response
+ )
+ )
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BaseBigtableTableAdminClient.list_authorized_views",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "ListAuthorizedViews",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _ListBackups(
+ _BaseBigtableTableAdminRestTransport._BaseListBackups,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.ListBackups")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.ListBackupsRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> bigtable_table_admin.ListBackupsResponse:
+ r"""Call the list backups method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.ListBackupsRequest):
+ The request object. The request for
+ [ListBackups][google.bigtable.admin.v2.BigtableTableAdmin.ListBackups].
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.bigtable_table_admin.ListBackupsResponse:
+ The response for
+ [ListBackups][google.bigtable.admin.v2.BigtableTableAdmin.ListBackups].
+
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseListBackups._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_list_backups(request, metadata)
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseListBackups._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseListBackups._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.ListBackups",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "ListBackups",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableTableAdminRestTransport._ListBackups._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = bigtable_table_admin.ListBackupsResponse()
+ pb_resp = bigtable_table_admin.ListBackupsResponse.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_list_backups(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_list_backups_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = bigtable_table_admin.ListBackupsResponse.to_json(
+ response
+ )
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BaseBigtableTableAdminClient.list_backups",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "ListBackups",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _ListSchemaBundles(
+ _BaseBigtableTableAdminRestTransport._BaseListSchemaBundles,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.ListSchemaBundles")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.ListSchemaBundlesRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> bigtable_table_admin.ListSchemaBundlesResponse:
+ r"""Call the list schema bundles method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.ListSchemaBundlesRequest):
+ The request object. The request for
+ [ListSchemaBundles][google.bigtable.admin.v2.BigtableTableAdmin.ListSchemaBundles].
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.bigtable_table_admin.ListSchemaBundlesResponse:
+ The response for
+ [ListSchemaBundles][google.bigtable.admin.v2.BigtableTableAdmin.ListSchemaBundles].
+
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseListSchemaBundles._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_list_schema_bundles(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseListSchemaBundles._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseListSchemaBundles._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.ListSchemaBundles",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "ListSchemaBundles",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableTableAdminRestTransport._ListSchemaBundles._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = bigtable_table_admin.ListSchemaBundlesResponse()
+ pb_resp = bigtable_table_admin.ListSchemaBundlesResponse.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_list_schema_bundles(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_list_schema_bundles_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = (
+ bigtable_table_admin.ListSchemaBundlesResponse.to_json(response)
+ )
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BaseBigtableTableAdminClient.list_schema_bundles",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "ListSchemaBundles",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _ListSnapshots(
+ _BaseBigtableTableAdminRestTransport._BaseListSnapshots,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.ListSnapshots")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.ListSnapshotsRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> bigtable_table_admin.ListSnapshotsResponse:
+ r"""Call the list snapshots method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.ListSnapshotsRequest):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots][google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots]
+
+ Note: This is a private alpha release of Cloud Bigtable
+ snapshots. This feature is not currently available to
+ most Cloud Bigtable customers. This feature might be
+ changed in backward-incompatible ways and is not
+ recommended for production use. It is not subject to any
+ SLA or deprecation policy.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.bigtable_table_admin.ListSnapshotsResponse:
+ Response message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots][google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots]
+
+ Note: This is a private alpha release of Cloud Bigtable
+ snapshots. This feature is not currently available to
+ most Cloud Bigtable customers. This feature might be
+ changed in backward-incompatible ways and is not
+ recommended for production use. It is not subject to any
+ SLA or deprecation policy.
+
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseListSnapshots._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_list_snapshots(request, metadata)
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseListSnapshots._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseListSnapshots._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.ListSnapshots",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "ListSnapshots",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableTableAdminRestTransport._ListSnapshots._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = bigtable_table_admin.ListSnapshotsResponse()
+ pb_resp = bigtable_table_admin.ListSnapshotsResponse.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_list_snapshots(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_list_snapshots_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = (
+ bigtable_table_admin.ListSnapshotsResponse.to_json(response)
+ )
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BaseBigtableTableAdminClient.list_snapshots",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "ListSnapshots",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _ListTables(
+ _BaseBigtableTableAdminRestTransport._BaseListTables, BigtableTableAdminRestStub
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.ListTables")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.ListTablesRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> bigtable_table_admin.ListTablesResponse:
+ r"""Call the list tables method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.ListTablesRequest):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.ListTables][google.bigtable.admin.v2.BigtableTableAdmin.ListTables]
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.bigtable_table_admin.ListTablesResponse:
+ Response message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.ListTables][google.bigtable.admin.v2.BigtableTableAdmin.ListTables]
+
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseListTables._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_list_tables(request, metadata)
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseListTables._get_transcoded_request(
+ http_options, request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseListTables._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.ListTables",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "ListTables",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableTableAdminRestTransport._ListTables._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = bigtable_table_admin.ListTablesResponse()
+ pb_resp = bigtable_table_admin.ListTablesResponse.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_list_tables(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_list_tables_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = bigtable_table_admin.ListTablesResponse.to_json(
+ response
+ )
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BaseBigtableTableAdminClient.list_tables",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "ListTables",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _ModifyColumnFamilies(
+ _BaseBigtableTableAdminRestTransport._BaseModifyColumnFamilies,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.ModifyColumnFamilies")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.ModifyColumnFamiliesRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> table.Table:
+ r"""Call the modify column families method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.ModifyColumnFamiliesRequest):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.ModifyColumnFamilies][google.bigtable.admin.v2.BigtableTableAdmin.ModifyColumnFamilies]
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.table.Table:
+ A collection of user data indexed by
+ row, column, and timestamp. Each table
+ is served using the resources of its
+ parent cluster.
+
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseModifyColumnFamilies._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_modify_column_families(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseModifyColumnFamilies._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableTableAdminRestTransport._BaseModifyColumnFamilies._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseModifyColumnFamilies._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.ModifyColumnFamilies",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "ModifyColumnFamilies",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = (
+ BigtableTableAdminRestTransport._ModifyColumnFamilies._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = table.Table()
+ pb_resp = table.Table.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_modify_column_families(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_modify_column_families_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = table.Table.to_json(response)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BaseBigtableTableAdminClient.modify_column_families",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "ModifyColumnFamilies",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _RestoreTable(
+ _BaseBigtableTableAdminRestTransport._BaseRestoreTable,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.RestoreTable")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.RestoreTableRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operations_pb2.Operation:
+ r"""Call the restore table method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.RestoreTableRequest):
+ The request object. The request for
+ [RestoreTable][google.bigtable.admin.v2.BigtableTableAdmin.RestoreTable].
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.operations_pb2.Operation:
+ This resource represents a
+ long-running operation that is the
+ result of a network API call.
+
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseRestoreTable._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_restore_table(request, metadata)
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseRestoreTable._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableTableAdminRestTransport._BaseRestoreTable._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseRestoreTable._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.RestoreTable",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "RestoreTable",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableTableAdminRestTransport._RestoreTable._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = operations_pb2.Operation()
+ json_format.Parse(response.content, resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_restore_table(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_restore_table_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = json_format.MessageToJson(resp)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BaseBigtableTableAdminClient.restore_table",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "RestoreTable",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _SetIamPolicy(
+ _BaseBigtableTableAdminRestTransport._BaseSetIamPolicy,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.SetIamPolicy")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: iam_policy_pb2.SetIamPolicyRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> policy_pb2.Policy:
+ r"""Call the set iam policy method over HTTP.
+
+ Args:
+ request (~.iam_policy_pb2.SetIamPolicyRequest):
+ The request object. Request message for ``SetIamPolicy`` method.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.policy_pb2.Policy:
+ An Identity and Access Management (IAM) policy, which
+ specifies access controls for Google Cloud resources.
+
+ A ``Policy`` is a collection of ``bindings``. A
+ ``binding`` binds one or more ``members``, or
+ principals, to a single ``role``. Principals can be user
+ accounts, service accounts, Google groups, and domains
+ (such as G Suite). A ``role`` is a named list of
+ permissions; each ``role`` can be an IAM predefined role
+ or a user-created custom role.
+
+ For some types of Google Cloud resources, a ``binding``
+ can also specify a ``condition``, which is a logical
+ expression that allows access to a resource only if the
+ expression evaluates to ``true``. A condition can add
+ constraints based on attributes of the request, the
+ resource, or both. To learn which resources support
+ conditions in their IAM policies, see the `IAM
+ documentation `__.
+
+ **JSON example:**
+
+ ::
+
+ {
+ "bindings": [
+ {
+ "role": "roles/resourcemanager.organizationAdmin",
+ "members": [
+ "user:mike@example.com",
+ "group:admins@example.com",
+ "domain:google.com",
+ "serviceAccount:my-project-id@appspot.gserviceaccount.com"
+ ]
+ },
+ {
+ "role": "roles/resourcemanager.organizationViewer",
+ "members": [
+ "user:eve@example.com"
+ ],
+ "condition": {
+ "title": "expirable access",
+ "description": "Does not grant access after Sep 2020",
+ "expression": "request.time <
+ timestamp('2020-10-01T00:00:00.000Z')",
+ }
+ }
+ ],
+ "etag": "BwWWja0YfJA=",
+ "version": 3
+ }
+
+ **YAML example:**
+
+ ::
+
+ bindings:
+ - members:
+ - user:mike@example.com
+ - group:admins@example.com
+ - domain:google.com
+ - serviceAccount:my-project-id@appspot.gserviceaccount.com
+ role: roles/resourcemanager.organizationAdmin
+ - members:
+ - user:eve@example.com
+ role: roles/resourcemanager.organizationViewer
+ condition:
+ title: expirable access
+ description: Does not grant access after Sep 2020
+ expression: request.time < timestamp('2020-10-01T00:00:00.000Z')
+ etag: BwWWja0YfJA=
+ version: 3
+
+ For a description of IAM and its features, see the `IAM
+ documentation `__.
+
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseSetIamPolicy._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_set_iam_policy(request, metadata)
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseSetIamPolicy._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableTableAdminRestTransport._BaseSetIamPolicy._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseSetIamPolicy._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.SetIamPolicy",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "SetIamPolicy",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableTableAdminRestTransport._SetIamPolicy._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = policy_pb2.Policy()
+ pb_resp = resp
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_set_iam_policy(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_set_iam_policy_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = json_format.MessageToJson(resp)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BaseBigtableTableAdminClient.set_iam_policy",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "SetIamPolicy",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _SnapshotTable(
+ _BaseBigtableTableAdminRestTransport._BaseSnapshotTable,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.SnapshotTable")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.SnapshotTableRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operations_pb2.Operation:
+ r"""Call the snapshot table method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.SnapshotTableRequest):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.SnapshotTable][google.bigtable.admin.v2.BigtableTableAdmin.SnapshotTable]
+
+ Note: This is a private alpha release of Cloud Bigtable
+ snapshots. This feature is not currently available to
+ most Cloud Bigtable customers. This feature might be
+ changed in backward-incompatible ways and is not
+ recommended for production use. It is not subject to any
+ SLA or deprecation policy.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.operations_pb2.Operation:
+ This resource represents a
+ long-running operation that is the
+ result of a network API call.
+
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseSnapshotTable._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_snapshot_table(request, metadata)
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseSnapshotTable._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableTableAdminRestTransport._BaseSnapshotTable._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseSnapshotTable._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.SnapshotTable",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "SnapshotTable",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableTableAdminRestTransport._SnapshotTable._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = operations_pb2.Operation()
+ json_format.Parse(response.content, resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_snapshot_table(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_snapshot_table_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = json_format.MessageToJson(resp)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BaseBigtableTableAdminClient.snapshot_table",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "SnapshotTable",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _TestIamPermissions(
+ _BaseBigtableTableAdminRestTransport._BaseTestIamPermissions,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.TestIamPermissions")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: iam_policy_pb2.TestIamPermissionsRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> iam_policy_pb2.TestIamPermissionsResponse:
+ r"""Call the test iam permissions method over HTTP.
+
+ Args:
+ request (~.iam_policy_pb2.TestIamPermissionsRequest):
+ The request object. Request message for ``TestIamPermissions`` method.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.iam_policy_pb2.TestIamPermissionsResponse:
+ Response message for ``TestIamPermissions`` method.
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseTestIamPermissions._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_test_iam_permissions(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseTestIamPermissions._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableTableAdminRestTransport._BaseTestIamPermissions._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseTestIamPermissions._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.TestIamPermissions",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "TestIamPermissions",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = (
+ BigtableTableAdminRestTransport._TestIamPermissions._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = iam_policy_pb2.TestIamPermissionsResponse()
+ pb_resp = resp
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_test_iam_permissions(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_test_iam_permissions_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = json_format.MessageToJson(resp)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BaseBigtableTableAdminClient.test_iam_permissions",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "TestIamPermissions",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _UndeleteTable(
+ _BaseBigtableTableAdminRestTransport._BaseUndeleteTable,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.UndeleteTable")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.UndeleteTableRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operations_pb2.Operation:
+ r"""Call the undelete table method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.UndeleteTableRequest):
+ The request object. Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.UndeleteTable][google.bigtable.admin.v2.BigtableTableAdmin.UndeleteTable]
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.operations_pb2.Operation:
+ This resource represents a
+ long-running operation that is the
+ result of a network API call.
+
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseUndeleteTable._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_undelete_table(request, metadata)
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseUndeleteTable._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableTableAdminRestTransport._BaseUndeleteTable._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseUndeleteTable._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.UndeleteTable",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "UndeleteTable",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableTableAdminRestTransport._UndeleteTable._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = operations_pb2.Operation()
+ json_format.Parse(response.content, resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_undelete_table(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_undelete_table_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = json_format.MessageToJson(resp)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BaseBigtableTableAdminClient.undelete_table",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "UndeleteTable",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _UpdateAuthorizedView(
+ _BaseBigtableTableAdminRestTransport._BaseUpdateAuthorizedView,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.UpdateAuthorizedView")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.UpdateAuthorizedViewRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operations_pb2.Operation:
+ r"""Call the update authorized view method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.UpdateAuthorizedViewRequest):
+ The request object. The request for
+ [UpdateAuthorizedView][google.bigtable.admin.v2.BigtableTableAdmin.UpdateAuthorizedView].
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.operations_pb2.Operation:
+ This resource represents a
+ long-running operation that is the
+ result of a network API call.
+
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseUpdateAuthorizedView._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_update_authorized_view(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseUpdateAuthorizedView._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableTableAdminRestTransport._BaseUpdateAuthorizedView._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseUpdateAuthorizedView._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.UpdateAuthorizedView",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "UpdateAuthorizedView",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = (
+ BigtableTableAdminRestTransport._UpdateAuthorizedView._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = operations_pb2.Operation()
+ json_format.Parse(response.content, resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_update_authorized_view(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_update_authorized_view_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = json_format.MessageToJson(resp)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BaseBigtableTableAdminClient.update_authorized_view",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "UpdateAuthorizedView",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _UpdateBackup(
+ _BaseBigtableTableAdminRestTransport._BaseUpdateBackup,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.UpdateBackup")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.UpdateBackupRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> table.Backup:
+ r"""Call the update backup method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.UpdateBackupRequest):
+ The request object. The request for
+ [UpdateBackup][google.bigtable.admin.v2.BigtableTableAdmin.UpdateBackup].
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.table.Backup:
+ A backup of a Cloud Bigtable table.
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseUpdateBackup._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_update_backup(request, metadata)
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseUpdateBackup._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableTableAdminRestTransport._BaseUpdateBackup._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseUpdateBackup._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.UpdateBackup",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "UpdateBackup",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableTableAdminRestTransport._UpdateBackup._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = table.Backup()
+ pb_resp = table.Backup.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_update_backup(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_update_backup_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = table.Backup.to_json(response)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BaseBigtableTableAdminClient.update_backup",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "UpdateBackup",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _UpdateSchemaBundle(
+ _BaseBigtableTableAdminRestTransport._BaseUpdateSchemaBundle,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.UpdateSchemaBundle")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.UpdateSchemaBundleRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operations_pb2.Operation:
+ r"""Call the update schema bundle method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.UpdateSchemaBundleRequest):
+ The request object. The request for
+ [UpdateSchemaBundle][google.bigtable.admin.v2.BigtableTableAdmin.UpdateSchemaBundle].
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.operations_pb2.Operation:
+ This resource represents a
+ long-running operation that is the
+ result of a network API call.
+
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseUpdateSchemaBundle._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_update_schema_bundle(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseUpdateSchemaBundle._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableTableAdminRestTransport._BaseUpdateSchemaBundle._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseUpdateSchemaBundle._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.UpdateSchemaBundle",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "UpdateSchemaBundle",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = (
+ BigtableTableAdminRestTransport._UpdateSchemaBundle._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = operations_pb2.Operation()
+ json_format.Parse(response.content, resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_update_schema_bundle(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_update_schema_bundle_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = json_format.MessageToJson(resp)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BaseBigtableTableAdminClient.update_schema_bundle",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "UpdateSchemaBundle",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _UpdateTable(
+ _BaseBigtableTableAdminRestTransport._BaseUpdateTable,
+ BigtableTableAdminRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableTableAdminRestTransport.UpdateTable")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable_table_admin.UpdateTableRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> operations_pb2.Operation:
+ r"""Call the update table method over HTTP.
+
+ Args:
+ request (~.bigtable_table_admin.UpdateTableRequest):
+ The request object. The request for
+ [UpdateTable][google.bigtable.admin.v2.BigtableTableAdmin.UpdateTable].
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.operations_pb2.Operation:
+ This resource represents a
+ long-running operation that is the
+ result of a network API call.
+
+ """
+
+ http_options = (
+ _BaseBigtableTableAdminRestTransport._BaseUpdateTable._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_update_table(request, metadata)
+ transcoded_request = _BaseBigtableTableAdminRestTransport._BaseUpdateTable._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableTableAdminRestTransport._BaseUpdateTable._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableTableAdminRestTransport._BaseUpdateTable._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = json_format.MessageToJson(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable.admin_v2.BaseBigtableTableAdminClient.UpdateTable",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "UpdateTable",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableTableAdminRestTransport._UpdateTable._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = operations_pb2.Operation()
+ json_format.Parse(response.content, resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_update_table(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_update_table_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = json_format.MessageToJson(resp)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable.admin_v2.BaseBigtableTableAdminClient.update_table",
+ extra={
+ "serviceName": "google.bigtable.admin.v2.BigtableTableAdmin",
+ "rpcName": "UpdateTable",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ @property
+ def check_consistency(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.CheckConsistencyRequest],
+ bigtable_table_admin.CheckConsistencyResponse,
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._CheckConsistency(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def copy_backup(
+ self,
+ ) -> Callable[[bigtable_table_admin.CopyBackupRequest], operations_pb2.Operation]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._CopyBackup(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def create_authorized_view(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.CreateAuthorizedViewRequest], operations_pb2.Operation
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._CreateAuthorizedView(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def create_backup(
+ self,
+ ) -> Callable[[bigtable_table_admin.CreateBackupRequest], operations_pb2.Operation]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._CreateBackup(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def create_schema_bundle(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.CreateSchemaBundleRequest], operations_pb2.Operation
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._CreateSchemaBundle(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def create_table(
+ self,
+ ) -> Callable[[bigtable_table_admin.CreateTableRequest], gba_table.Table]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._CreateTable(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def create_table_from_snapshot(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.CreateTableFromSnapshotRequest], operations_pb2.Operation
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._CreateTableFromSnapshot(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def delete_authorized_view(
+ self,
+ ) -> Callable[[bigtable_table_admin.DeleteAuthorizedViewRequest], empty_pb2.Empty]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._DeleteAuthorizedView(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def delete_backup(
+ self,
+ ) -> Callable[[bigtable_table_admin.DeleteBackupRequest], empty_pb2.Empty]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._DeleteBackup(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def delete_schema_bundle(
+ self,
+ ) -> Callable[[bigtable_table_admin.DeleteSchemaBundleRequest], empty_pb2.Empty]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._DeleteSchemaBundle(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def delete_snapshot(
+ self,
+ ) -> Callable[[bigtable_table_admin.DeleteSnapshotRequest], empty_pb2.Empty]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._DeleteSnapshot(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def delete_table(
+ self,
+ ) -> Callable[[bigtable_table_admin.DeleteTableRequest], empty_pb2.Empty]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._DeleteTable(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def drop_row_range(
+ self,
+ ) -> Callable[[bigtable_table_admin.DropRowRangeRequest], empty_pb2.Empty]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._DropRowRange(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def generate_consistency_token(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.GenerateConsistencyTokenRequest],
+ bigtable_table_admin.GenerateConsistencyTokenResponse,
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._GenerateConsistencyToken(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def get_authorized_view(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.GetAuthorizedViewRequest], table.AuthorizedView
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._GetAuthorizedView(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def get_backup(
+ self,
+ ) -> Callable[[bigtable_table_admin.GetBackupRequest], table.Backup]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._GetBackup(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def get_iam_policy(
+ self,
+ ) -> Callable[[iam_policy_pb2.GetIamPolicyRequest], policy_pb2.Policy]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._GetIamPolicy(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def get_schema_bundle(
+ self,
+ ) -> Callable[[bigtable_table_admin.GetSchemaBundleRequest], table.SchemaBundle]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._GetSchemaBundle(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def get_snapshot(
+ self,
+ ) -> Callable[[bigtable_table_admin.GetSnapshotRequest], table.Snapshot]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._GetSnapshot(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def get_table(
+ self,
+ ) -> Callable[[bigtable_table_admin.GetTableRequest], table.Table]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._GetTable(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def list_authorized_views(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.ListAuthorizedViewsRequest],
+ bigtable_table_admin.ListAuthorizedViewsResponse,
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._ListAuthorizedViews(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def list_backups(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.ListBackupsRequest],
+ bigtable_table_admin.ListBackupsResponse,
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._ListBackups(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def list_schema_bundles(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.ListSchemaBundlesRequest],
+ bigtable_table_admin.ListSchemaBundlesResponse,
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._ListSchemaBundles(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def list_snapshots(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.ListSnapshotsRequest],
+ bigtable_table_admin.ListSnapshotsResponse,
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._ListSnapshots(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def list_tables(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.ListTablesRequest],
+ bigtable_table_admin.ListTablesResponse,
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._ListTables(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def modify_column_families(
+ self,
+ ) -> Callable[[bigtable_table_admin.ModifyColumnFamiliesRequest], table.Table]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._ModifyColumnFamilies(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def restore_table(
+ self,
+ ) -> Callable[[bigtable_table_admin.RestoreTableRequest], operations_pb2.Operation]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._RestoreTable(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def set_iam_policy(
+ self,
+ ) -> Callable[[iam_policy_pb2.SetIamPolicyRequest], policy_pb2.Policy]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._SetIamPolicy(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def snapshot_table(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.SnapshotTableRequest], operations_pb2.Operation
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._SnapshotTable(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def test_iam_permissions(
+ self,
+ ) -> Callable[
+ [iam_policy_pb2.TestIamPermissionsRequest],
+ iam_policy_pb2.TestIamPermissionsResponse,
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._TestIamPermissions(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def undelete_table(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.UndeleteTableRequest], operations_pb2.Operation
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._UndeleteTable(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def update_authorized_view(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.UpdateAuthorizedViewRequest], operations_pb2.Operation
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._UpdateAuthorizedView(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def update_backup(
+ self,
+ ) -> Callable[[bigtable_table_admin.UpdateBackupRequest], table.Backup]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._UpdateBackup(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def update_schema_bundle(
+ self,
+ ) -> Callable[
+ [bigtable_table_admin.UpdateSchemaBundleRequest], operations_pb2.Operation
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._UpdateSchemaBundle(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def update_table(
+ self,
+ ) -> Callable[[bigtable_table_admin.UpdateTableRequest], operations_pb2.Operation]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._UpdateTable(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def kind(self) -> str:
+ return "rest"
+
+ def close(self):
+ self._session.close()
+
+
+__all__ = ("BigtableTableAdminRestTransport",)
diff --git a/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/rest_base.py b/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/rest_base.py
new file mode 100644
index 000000000..ef6c2374d
--- /dev/null
+++ b/google/cloud/bigtable_admin_v2/services/bigtable_table_admin/transports/rest_base.py
@@ -0,0 +1,2001 @@
+# -*- coding: utf-8 -*-
+# Copyright 2025 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 json # type: ignore
+from google.api_core import path_template
+from google.api_core import gapic_v1
+
+from google.protobuf import json_format
+from .base import BigtableTableAdminTransport, DEFAULT_CLIENT_INFO
+
+import re
+from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union
+
+
+from google.cloud.bigtable_admin_v2.types import bigtable_table_admin
+from google.cloud.bigtable_admin_v2.types import table
+from google.cloud.bigtable_admin_v2.types import table as gba_table
+from google.iam.v1 import iam_policy_pb2 # type: ignore
+from google.iam.v1 import policy_pb2 # type: ignore
+from google.protobuf import empty_pb2 # type: ignore
+from google.longrunning import operations_pb2 # type: ignore
+
+
+class _BaseBigtableTableAdminRestTransport(BigtableTableAdminTransport):
+ """Base REST backend transport for BigtableTableAdmin.
+
+ Note: This class is not meant to be used directly. Use its sync and
+ async sub-classes instead.
+
+ This class defines the same methods as the primary client, so the
+ primary client can load the underlying transport implementation
+ and call it.
+
+ It sends JSON representations of protocol buffers over HTTP/1.1
+ """
+
+ def __init__(
+ self,
+ *,
+ host: str = "bigtableadmin.googleapis.com",
+ credentials: Optional[Any] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ always_use_jwt_access: Optional[bool] = False,
+ url_scheme: str = "https",
+ api_audience: Optional[str] = None,
+ ) -> None:
+ """Instantiate the transport.
+ Args:
+ host (Optional[str]):
+ The hostname to connect to (default: 'bigtableadmin.googleapis.com').
+ credentials (Optional[Any]): The
+ authorization credentials to attach to requests. These
+ credentials identify the application to the service; if none
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you are developing
+ your own client library.
+ always_use_jwt_access (Optional[bool]): Whether self signed JWT should
+ be used for service account credentials.
+ url_scheme: the protocol scheme for the API endpoint. Normally
+ "https", but for testing or local servers,
+ "http" can be specified.
+ """
+ # Run the base constructor
+ maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host)
+ if maybe_url_match is None:
+ raise ValueError(
+ f"Unexpected hostname structure: {host}"
+ ) # pragma: NO COVER
+
+ url_match_items = maybe_url_match.groupdict()
+
+ host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host
+
+ super().__init__(
+ host=host,
+ credentials=credentials,
+ client_info=client_info,
+ always_use_jwt_access=always_use_jwt_access,
+ api_audience=api_audience,
+ )
+
+ class _BaseCheckConsistency:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{name=projects/*/instances/*/tables/*}:checkConsistency",
+ "body": "*",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.CheckConsistencyRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseCheckConsistency._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseCopyBackup:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{parent=projects/*/instances/*/clusters/*}/backups:copy",
+ "body": "*",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.CopyBackupRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseCopyBackup._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseCreateAuthorizedView:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {
+ "authorizedViewId": "",
+ }
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{parent=projects/*/instances/*/tables/*}/authorizedViews",
+ "body": "authorized_view",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.CreateAuthorizedViewRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseCreateAuthorizedView._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseCreateBackup:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {
+ "backupId": "",
+ }
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{parent=projects/*/instances/*/clusters/*}/backups",
+ "body": "backup",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.CreateBackupRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseCreateBackup._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseCreateSchemaBundle:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {
+ "schemaBundleId": "",
+ }
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{parent=projects/*/instances/*/tables/*}/schemaBundles",
+ "body": "schema_bundle",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.CreateSchemaBundleRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseCreateSchemaBundle._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseCreateTable:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{parent=projects/*/instances/*}/tables",
+ "body": "*",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.CreateTableRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseCreateTable._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseCreateTableFromSnapshot:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{parent=projects/*/instances/*}/tables:createFromSnapshot",
+ "body": "*",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.CreateTableFromSnapshotRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseCreateTableFromSnapshot._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseDeleteAuthorizedView:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "delete",
+ "uri": "/v2/{name=projects/*/instances/*/tables/*/authorizedViews/*}",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.DeleteAuthorizedViewRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseDeleteAuthorizedView._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseDeleteBackup:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "delete",
+ "uri": "/v2/{name=projects/*/instances/*/clusters/*/backups/*}",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.DeleteBackupRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseDeleteBackup._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseDeleteSchemaBundle:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "delete",
+ "uri": "/v2/{name=projects/*/instances/*/tables/*/schemaBundles/*}",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.DeleteSchemaBundleRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseDeleteSchemaBundle._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseDeleteSnapshot:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "delete",
+ "uri": "/v2/{name=projects/*/instances/*/clusters/*/snapshots/*}",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.DeleteSnapshotRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseDeleteSnapshot._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseDeleteTable:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "delete",
+ "uri": "/v2/{name=projects/*/instances/*/tables/*}",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.DeleteTableRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseDeleteTable._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseDropRowRange:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{name=projects/*/instances/*/tables/*}:dropRowRange",
+ "body": "*",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.DropRowRangeRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseDropRowRange._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseGenerateConsistencyToken:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{name=projects/*/instances/*/tables/*}:generateConsistencyToken",
+ "body": "*",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.GenerateConsistencyTokenRequest.pb(
+ request
+ )
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseGenerateConsistencyToken._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseGetAuthorizedView:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "get",
+ "uri": "/v2/{name=projects/*/instances/*/tables/*/authorizedViews/*}",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.GetAuthorizedViewRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseGetAuthorizedView._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseGetBackup:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "get",
+ "uri": "/v2/{name=projects/*/instances/*/clusters/*/backups/*}",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.GetBackupRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseGetBackup._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseGetIamPolicy:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{resource=projects/*/instances/*/tables/*}:getIamPolicy",
+ "body": "*",
+ },
+ {
+ "method": "post",
+ "uri": "/v2/{resource=projects/*/instances/*/clusters/*/backups/*}:getIamPolicy",
+ "body": "*",
+ },
+ {
+ "method": "post",
+ "uri": "/v2/{resource=projects/*/instances/*/tables/*/authorizedViews/*}:getIamPolicy",
+ "body": "*",
+ },
+ {
+ "method": "post",
+ "uri": "/v2/{resource=projects/*/instances/*/tables/*/schemaBundles/*}:getIamPolicy",
+ "body": "*",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = request
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseGetIamPolicy._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseGetSchemaBundle:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "get",
+ "uri": "/v2/{name=projects/*/instances/*/tables/*/schemaBundles/*}",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.GetSchemaBundleRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseGetSchemaBundle._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseGetSnapshot:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "get",
+ "uri": "/v2/{name=projects/*/instances/*/clusters/*/snapshots/*}",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.GetSnapshotRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseGetSnapshot._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseGetTable:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "get",
+ "uri": "/v2/{name=projects/*/instances/*/tables/*}",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.GetTableRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseGetTable._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseListAuthorizedViews:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "get",
+ "uri": "/v2/{parent=projects/*/instances/*/tables/*}/authorizedViews",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.ListAuthorizedViewsRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseListAuthorizedViews._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseListBackups:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "get",
+ "uri": "/v2/{parent=projects/*/instances/*/clusters/*}/backups",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.ListBackupsRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseListBackups._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseListSchemaBundles:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "get",
+ "uri": "/v2/{parent=projects/*/instances/*/tables/*}/schemaBundles",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.ListSchemaBundlesRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseListSchemaBundles._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseListSnapshots:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "get",
+ "uri": "/v2/{parent=projects/*/instances/*/clusters/*}/snapshots",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.ListSnapshotsRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseListSnapshots._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseListTables:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "get",
+ "uri": "/v2/{parent=projects/*/instances/*}/tables",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.ListTablesRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseListTables._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseModifyColumnFamilies:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{name=projects/*/instances/*/tables/*}:modifyColumnFamilies",
+ "body": "*",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.ModifyColumnFamiliesRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseModifyColumnFamilies._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseRestoreTable:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{parent=projects/*/instances/*}/tables:restore",
+ "body": "*",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.RestoreTableRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseRestoreTable._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseSetIamPolicy:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{resource=projects/*/instances/*/tables/*}:setIamPolicy",
+ "body": "*",
+ },
+ {
+ "method": "post",
+ "uri": "/v2/{resource=projects/*/instances/*/clusters/*/backups/*}:setIamPolicy",
+ "body": "*",
+ },
+ {
+ "method": "post",
+ "uri": "/v2/{resource=projects/*/instances/*/tables/*/authorizedViews/*}:setIamPolicy",
+ "body": "*",
+ },
+ {
+ "method": "post",
+ "uri": "/v2/{resource=projects/*/instances/*/tables/*/schemaBundles/*}:setIamPolicy",
+ "body": "*",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = request
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseSetIamPolicy._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseSnapshotTable:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{name=projects/*/instances/*/tables/*}:snapshot",
+ "body": "*",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.SnapshotTableRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseSnapshotTable._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseTestIamPermissions:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{resource=projects/*/instances/*/tables/*}:testIamPermissions",
+ "body": "*",
+ },
+ {
+ "method": "post",
+ "uri": "/v2/{resource=projects/*/instances/*/clusters/*/backups/*}:testIamPermissions",
+ "body": "*",
+ },
+ {
+ "method": "post",
+ "uri": "/v2/{resource=projects/*/instances/*/tables/*/authorizedViews/*}:testIamPermissions",
+ "body": "*",
+ },
+ {
+ "method": "post",
+ "uri": "/v2/{resource=projects/*/instances/*/tables/*/schemaBundles/*}:testIamPermissions",
+ "body": "*",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = request
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseTestIamPermissions._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseUndeleteTable:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{name=projects/*/instances/*/tables/*}:undelete",
+ "body": "*",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.UndeleteTableRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseUndeleteTable._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseUpdateAuthorizedView:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "patch",
+ "uri": "/v2/{authorized_view.name=projects/*/instances/*/tables/*/authorizedViews/*}",
+ "body": "authorized_view",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.UpdateAuthorizedViewRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseUpdateAuthorizedView._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseUpdateBackup:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {
+ "updateMask": {},
+ }
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "patch",
+ "uri": "/v2/{backup.name=projects/*/instances/*/clusters/*/backups/*}",
+ "body": "backup",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.UpdateBackupRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseUpdateBackup._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseUpdateSchemaBundle:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "patch",
+ "uri": "/v2/{schema_bundle.name=projects/*/instances/*/tables/*/schemaBundles/*}",
+ "body": "schema_bundle",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.UpdateSchemaBundleRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseUpdateSchemaBundle._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseUpdateTable:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {
+ "updateMask": {},
+ }
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "patch",
+ "uri": "/v2/{table.name=projects/*/instances/*/tables/*}",
+ "body": "table",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable_table_admin.UpdateTableRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableTableAdminRestTransport._BaseUpdateTable._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+
+__all__ = ("_BaseBigtableTableAdminRestTransport",)
diff --git a/google/cloud/bigtable_admin_v2/types/__init__.py b/google/cloud/bigtable_admin_v2/types/__init__.py
index f35f0f4ab..d2036c7a3 100644
--- a/google/cloud/bigtable_admin_v2/types/__init__.py
+++ b/google/cloud/bigtable_admin_v2/types/__init__.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -19,12 +19,20 @@
CreateClusterRequest,
CreateInstanceMetadata,
CreateInstanceRequest,
+ CreateLogicalViewMetadata,
+ CreateLogicalViewRequest,
+ CreateMaterializedViewMetadata,
+ CreateMaterializedViewRequest,
DeleteAppProfileRequest,
DeleteClusterRequest,
DeleteInstanceRequest,
+ DeleteLogicalViewRequest,
+ DeleteMaterializedViewRequest,
GetAppProfileRequest,
GetClusterRequest,
GetInstanceRequest,
+ GetLogicalViewRequest,
+ GetMaterializedViewRequest,
ListAppProfilesRequest,
ListAppProfilesResponse,
ListClustersRequest,
@@ -33,6 +41,10 @@
ListHotTabletsResponse,
ListInstancesRequest,
ListInstancesResponse,
+ ListLogicalViewsRequest,
+ ListLogicalViewsResponse,
+ ListMaterializedViewsRequest,
+ ListMaterializedViewsResponse,
PartialUpdateClusterMetadata,
PartialUpdateClusterRequest,
PartialUpdateInstanceRequest,
@@ -40,26 +52,45 @@
UpdateAppProfileRequest,
UpdateClusterMetadata,
UpdateInstanceMetadata,
+ UpdateLogicalViewMetadata,
+ UpdateLogicalViewRequest,
+ UpdateMaterializedViewMetadata,
+ UpdateMaterializedViewRequest,
)
from .bigtable_table_admin import (
CheckConsistencyRequest,
CheckConsistencyResponse,
+ CopyBackupMetadata,
+ CopyBackupRequest,
+ CreateAuthorizedViewMetadata,
+ CreateAuthorizedViewRequest,
CreateBackupMetadata,
CreateBackupRequest,
+ CreateSchemaBundleMetadata,
+ CreateSchemaBundleRequest,
CreateTableFromSnapshotMetadata,
CreateTableFromSnapshotRequest,
CreateTableRequest,
+ DataBoostReadLocalWrites,
+ DeleteAuthorizedViewRequest,
DeleteBackupRequest,
+ DeleteSchemaBundleRequest,
DeleteSnapshotRequest,
DeleteTableRequest,
DropRowRangeRequest,
GenerateConsistencyTokenRequest,
GenerateConsistencyTokenResponse,
+ GetAuthorizedViewRequest,
GetBackupRequest,
+ GetSchemaBundleRequest,
GetSnapshotRequest,
GetTableRequest,
+ ListAuthorizedViewsRequest,
+ ListAuthorizedViewsResponse,
ListBackupsRequest,
ListBackupsResponse,
+ ListSchemaBundlesRequest,
+ ListSchemaBundlesResponse,
ListSnapshotsRequest,
ListSnapshotsResponse,
ListTablesRequest,
@@ -70,7 +101,16 @@
RestoreTableRequest,
SnapshotTableMetadata,
SnapshotTableRequest,
+ StandardReadRemoteWrites,
+ UndeleteTableMetadata,
+ UndeleteTableRequest,
+ UpdateAuthorizedViewMetadata,
+ UpdateAuthorizedViewRequest,
UpdateBackupRequest,
+ UpdateSchemaBundleMetadata,
+ UpdateSchemaBundleRequest,
+ UpdateTableMetadata,
+ UpdateTableRequest,
)
from .common import (
OperationProgress,
@@ -83,18 +123,29 @@
Cluster,
HotTablet,
Instance,
+ LogicalView,
+ MaterializedView,
)
from .table import (
+ AuthorizedView,
Backup,
BackupInfo,
+ ChangeStreamConfig,
ColumnFamily,
EncryptionInfo,
GcRule,
+ ProtoSchema,
RestoreInfo,
+ SchemaBundle,
Snapshot,
Table,
+ TieredStorageConfig,
+ TieredStorageRule,
RestoreSourceType,
)
+from .types import (
+ Type,
+)
__all__ = (
"CreateAppProfileRequest",
@@ -102,12 +153,20 @@
"CreateClusterRequest",
"CreateInstanceMetadata",
"CreateInstanceRequest",
+ "CreateLogicalViewMetadata",
+ "CreateLogicalViewRequest",
+ "CreateMaterializedViewMetadata",
+ "CreateMaterializedViewRequest",
"DeleteAppProfileRequest",
"DeleteClusterRequest",
"DeleteInstanceRequest",
+ "DeleteLogicalViewRequest",
+ "DeleteMaterializedViewRequest",
"GetAppProfileRequest",
"GetClusterRequest",
"GetInstanceRequest",
+ "GetLogicalViewRequest",
+ "GetMaterializedViewRequest",
"ListAppProfilesRequest",
"ListAppProfilesResponse",
"ListClustersRequest",
@@ -116,6 +175,10 @@
"ListHotTabletsResponse",
"ListInstancesRequest",
"ListInstancesResponse",
+ "ListLogicalViewsRequest",
+ "ListLogicalViewsResponse",
+ "ListMaterializedViewsRequest",
+ "ListMaterializedViewsResponse",
"PartialUpdateClusterMetadata",
"PartialUpdateClusterRequest",
"PartialUpdateInstanceRequest",
@@ -123,24 +186,43 @@
"UpdateAppProfileRequest",
"UpdateClusterMetadata",
"UpdateInstanceMetadata",
+ "UpdateLogicalViewMetadata",
+ "UpdateLogicalViewRequest",
+ "UpdateMaterializedViewMetadata",
+ "UpdateMaterializedViewRequest",
"CheckConsistencyRequest",
"CheckConsistencyResponse",
+ "CopyBackupMetadata",
+ "CopyBackupRequest",
+ "CreateAuthorizedViewMetadata",
+ "CreateAuthorizedViewRequest",
"CreateBackupMetadata",
"CreateBackupRequest",
+ "CreateSchemaBundleMetadata",
+ "CreateSchemaBundleRequest",
"CreateTableFromSnapshotMetadata",
"CreateTableFromSnapshotRequest",
"CreateTableRequest",
+ "DataBoostReadLocalWrites",
+ "DeleteAuthorizedViewRequest",
"DeleteBackupRequest",
+ "DeleteSchemaBundleRequest",
"DeleteSnapshotRequest",
"DeleteTableRequest",
"DropRowRangeRequest",
"GenerateConsistencyTokenRequest",
"GenerateConsistencyTokenResponse",
+ "GetAuthorizedViewRequest",
"GetBackupRequest",
+ "GetSchemaBundleRequest",
"GetSnapshotRequest",
"GetTableRequest",
+ "ListAuthorizedViewsRequest",
+ "ListAuthorizedViewsResponse",
"ListBackupsRequest",
"ListBackupsResponse",
+ "ListSchemaBundlesRequest",
+ "ListSchemaBundlesResponse",
"ListSnapshotsRequest",
"ListSnapshotsResponse",
"ListTablesRequest",
@@ -151,7 +233,16 @@
"RestoreTableRequest",
"SnapshotTableMetadata",
"SnapshotTableRequest",
+ "StandardReadRemoteWrites",
+ "UndeleteTableMetadata",
+ "UndeleteTableRequest",
+ "UpdateAuthorizedViewMetadata",
+ "UpdateAuthorizedViewRequest",
"UpdateBackupRequest",
+ "UpdateSchemaBundleMetadata",
+ "UpdateSchemaBundleRequest",
+ "UpdateTableMetadata",
+ "UpdateTableRequest",
"OperationProgress",
"StorageType",
"AppProfile",
@@ -160,13 +251,22 @@
"Cluster",
"HotTablet",
"Instance",
+ "LogicalView",
+ "MaterializedView",
+ "AuthorizedView",
"Backup",
"BackupInfo",
+ "ChangeStreamConfig",
"ColumnFamily",
"EncryptionInfo",
"GcRule",
+ "ProtoSchema",
"RestoreInfo",
+ "SchemaBundle",
"Snapshot",
"Table",
+ "TieredStorageConfig",
+ "TieredStorageRule",
"RestoreSourceType",
+ "Type",
)
diff --git a/google/cloud/bigtable_admin_v2/types/bigtable_instance_admin.py b/google/cloud/bigtable_admin_v2/types/bigtable_instance_admin.py
index 36ad5dc9c..4197ed0b7 100644
--- a/google/cloud/bigtable_admin_v2/types/bigtable_instance_admin.py
+++ b/google/cloud/bigtable_admin_v2/types/bigtable_instance_admin.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -13,6 +13,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+from __future__ import annotations
+
+from typing import MutableMapping, MutableSequence
+
import proto # type: ignore
from google.cloud.bigtable_admin_v2.types import instance as gba_instance
@@ -49,6 +53,22 @@
"UpdateAppProfileMetadata",
"ListHotTabletsRequest",
"ListHotTabletsResponse",
+ "CreateLogicalViewRequest",
+ "CreateLogicalViewMetadata",
+ "GetLogicalViewRequest",
+ "ListLogicalViewsRequest",
+ "ListLogicalViewsResponse",
+ "UpdateLogicalViewRequest",
+ "UpdateLogicalViewMetadata",
+ "DeleteLogicalViewRequest",
+ "CreateMaterializedViewRequest",
+ "CreateMaterializedViewMetadata",
+ "GetMaterializedViewRequest",
+ "ListMaterializedViewsRequest",
+ "ListMaterializedViewsResponse",
+ "UpdateMaterializedViewRequest",
+ "UpdateMaterializedViewMetadata",
+ "DeleteMaterializedViewRequest",
},
)
@@ -68,29 +88,28 @@ class CreateInstanceRequest(proto.Message):
instance (google.cloud.bigtable_admin_v2.types.Instance):
Required. The instance to create. Fields marked
``OutputOnly`` must be left blank.
- clusters (Mapping[str, google.cloud.bigtable_admin_v2.types.Cluster]):
+ clusters (MutableMapping[str, google.cloud.bigtable_admin_v2.types.Cluster]):
Required. The clusters to be created within the instance,
mapped by desired cluster ID, e.g., just ``mycluster``
rather than
``projects/myproject/instances/myinstance/clusters/mycluster``.
- Fields marked ``OutputOnly`` must be left blank. Currently,
- at most four clusters can be specified.
+ Fields marked ``OutputOnly`` must be left blank.
"""
- parent = proto.Field(
+ parent: str = proto.Field(
proto.STRING,
number=1,
)
- instance_id = proto.Field(
+ instance_id: str = proto.Field(
proto.STRING,
number=2,
)
- instance = proto.Field(
+ instance: gba_instance.Instance = proto.Field(
proto.MESSAGE,
number=3,
message=gba_instance.Instance,
)
- clusters = proto.MapField(
+ clusters: MutableMapping[str, gba_instance.Cluster] = proto.MapField(
proto.STRING,
proto.MESSAGE,
number=4,
@@ -107,7 +126,7 @@ class GetInstanceRequest(proto.Message):
are of the form ``projects/{project}/instances/{instance}``.
"""
- name = proto.Field(
+ name: str = proto.Field(
proto.STRING,
number=1,
)
@@ -125,11 +144,11 @@ class ListInstancesRequest(proto.Message):
DEPRECATED: This field is unused and ignored.
"""
- parent = proto.Field(
+ parent: str = proto.Field(
proto.STRING,
number=1,
)
- page_token = proto.Field(
+ page_token: str = proto.Field(
proto.STRING,
number=2,
)
@@ -139,9 +158,9 @@ class ListInstancesResponse(proto.Message):
r"""Response message for BigtableInstanceAdmin.ListInstances.
Attributes:
- instances (Sequence[google.cloud.bigtable_admin_v2.types.Instance]):
+ instances (MutableSequence[google.cloud.bigtable_admin_v2.types.Instance]):
The list of requested instances.
- failed_locations (Sequence[str]):
+ failed_locations (MutableSequence[str]):
Locations from which Instance information could not be
retrieved, due to an outage or some other transient
condition. Instances whose Clusters are all in one of the
@@ -157,16 +176,16 @@ class ListInstancesResponse(proto.Message):
def raw_page(self):
return self
- instances = proto.RepeatedField(
+ instances: MutableSequence[gba_instance.Instance] = proto.RepeatedField(
proto.MESSAGE,
number=1,
message=gba_instance.Instance,
)
- failed_locations = proto.RepeatedField(
+ failed_locations: MutableSequence[str] = proto.RepeatedField(
proto.STRING,
number=2,
)
- next_page_token = proto.Field(
+ next_page_token: str = proto.Field(
proto.STRING,
number=3,
)
@@ -185,12 +204,12 @@ class PartialUpdateInstanceRequest(proto.Message):
should be replaced. Must be explicitly set.
"""
- instance = proto.Field(
+ instance: gba_instance.Instance = proto.Field(
proto.MESSAGE,
number=1,
message=gba_instance.Instance,
)
- update_mask = proto.Field(
+ update_mask: field_mask_pb2.FieldMask = proto.Field(
proto.MESSAGE,
number=2,
message=field_mask_pb2.FieldMask,
@@ -207,7 +226,7 @@ class DeleteInstanceRequest(proto.Message):
``projects/{project}/instances/{instance}``.
"""
- name = proto.Field(
+ name: str = proto.Field(
proto.STRING,
number=1,
)
@@ -231,15 +250,15 @@ class CreateClusterRequest(proto.Message):
``OutputOnly`` must be left blank.
"""
- parent = proto.Field(
+ parent: str = proto.Field(
proto.STRING,
number=1,
)
- cluster_id = proto.Field(
+ cluster_id: str = proto.Field(
proto.STRING,
number=2,
)
- cluster = proto.Field(
+ cluster: gba_instance.Cluster = proto.Field(
proto.MESSAGE,
number=3,
message=gba_instance.Cluster,
@@ -256,7 +275,7 @@ class GetClusterRequest(proto.Message):
``projects/{project}/instances/{instance}/clusters/{cluster}``.
"""
- name = proto.Field(
+ name: str = proto.Field(
proto.STRING,
number=1,
)
@@ -276,11 +295,11 @@ class ListClustersRequest(proto.Message):
DEPRECATED: This field is unused and ignored.
"""
- parent = proto.Field(
+ parent: str = proto.Field(
proto.STRING,
number=1,
)
- page_token = proto.Field(
+ page_token: str = proto.Field(
proto.STRING,
number=2,
)
@@ -290,9 +309,9 @@ class ListClustersResponse(proto.Message):
r"""Response message for BigtableInstanceAdmin.ListClusters.
Attributes:
- clusters (Sequence[google.cloud.bigtable_admin_v2.types.Cluster]):
+ clusters (MutableSequence[google.cloud.bigtable_admin_v2.types.Cluster]):
The list of requested clusters.
- failed_locations (Sequence[str]):
+ failed_locations (MutableSequence[str]):
Locations from which Cluster information could not be
retrieved, due to an outage or some other transient
condition. Clusters from these locations may be missing from
@@ -307,16 +326,16 @@ class ListClustersResponse(proto.Message):
def raw_page(self):
return self
- clusters = proto.RepeatedField(
+ clusters: MutableSequence[gba_instance.Cluster] = proto.RepeatedField(
proto.MESSAGE,
number=1,
message=gba_instance.Cluster,
)
- failed_locations = proto.RepeatedField(
+ failed_locations: MutableSequence[str] = proto.RepeatedField(
proto.STRING,
number=2,
)
- next_page_token = proto.Field(
+ next_page_token: str = proto.Field(
proto.STRING,
number=3,
)
@@ -332,7 +351,7 @@ class DeleteClusterRequest(proto.Message):
``projects/{project}/instances/{instance}/clusters/{cluster}``.
"""
- name = proto.Field(
+ name: str = proto.Field(
proto.STRING,
number=1,
)
@@ -353,17 +372,17 @@ class CreateInstanceMetadata(proto.Message):
completed successfully.
"""
- original_request = proto.Field(
+ original_request: "CreateInstanceRequest" = proto.Field(
proto.MESSAGE,
number=1,
message="CreateInstanceRequest",
)
- request_time = proto.Field(
+ request_time: timestamp_pb2.Timestamp = proto.Field(
proto.MESSAGE,
number=2,
message=timestamp_pb2.Timestamp,
)
- finish_time = proto.Field(
+ finish_time: timestamp_pb2.Timestamp = proto.Field(
proto.MESSAGE,
number=3,
message=timestamp_pb2.Timestamp,
@@ -385,17 +404,17 @@ class UpdateInstanceMetadata(proto.Message):
completed successfully.
"""
- original_request = proto.Field(
+ original_request: "PartialUpdateInstanceRequest" = proto.Field(
proto.MESSAGE,
number=1,
message="PartialUpdateInstanceRequest",
)
- request_time = proto.Field(
+ request_time: timestamp_pb2.Timestamp = proto.Field(
proto.MESSAGE,
number=2,
message=timestamp_pb2.Timestamp,
)
- finish_time = proto.Field(
+ finish_time: timestamp_pb2.Timestamp = proto.Field(
proto.MESSAGE,
number=3,
message=timestamp_pb2.Timestamp,
@@ -415,7 +434,7 @@ class CreateClusterMetadata(proto.Message):
finish_time (google.protobuf.timestamp_pb2.Timestamp):
The time at which the operation failed or was
completed successfully.
- tables (Mapping[str, google.cloud.bigtable_admin_v2.types.CreateClusterMetadata.TableProgress]):
+ tables (MutableMapping[str, google.cloud.bigtable_admin_v2.types.CreateClusterMetadata.TableProgress]):
Keys: the full ``name`` of each table that existed in the
instance when CreateCluster was first called, i.e.
``projects//instances//tables/``.
@@ -442,43 +461,62 @@ class TableProgress(proto.Message):
"""
class State(proto.Enum):
- r""""""
+ r"""
+
+ Values:
+ STATE_UNSPECIFIED (0):
+ No description available.
+ PENDING (1):
+ The table has not yet begun copying to the
+ new cluster.
+ COPYING (2):
+ The table is actively being copied to the new
+ cluster.
+ COMPLETED (3):
+ The table has been fully copied to the new
+ cluster.
+ CANCELLED (4):
+ The table was deleted before it finished
+ copying to the new cluster. Note that tables
+ deleted after completion will stay marked as
+ COMPLETED, not CANCELLED.
+ """
STATE_UNSPECIFIED = 0
PENDING = 1
COPYING = 2
COMPLETED = 3
CANCELLED = 4
- estimated_size_bytes = proto.Field(
+ estimated_size_bytes: int = proto.Field(
proto.INT64,
number=2,
)
- estimated_copied_bytes = proto.Field(
+ estimated_copied_bytes: int = proto.Field(
proto.INT64,
number=3,
)
- state = proto.Field(
+ state: "CreateClusterMetadata.TableProgress.State" = proto.Field(
proto.ENUM,
number=4,
enum="CreateClusterMetadata.TableProgress.State",
)
- original_request = proto.Field(
+ original_request: "CreateClusterRequest" = proto.Field(
proto.MESSAGE,
number=1,
message="CreateClusterRequest",
)
- request_time = proto.Field(
+ request_time: timestamp_pb2.Timestamp = proto.Field(
proto.MESSAGE,
number=2,
message=timestamp_pb2.Timestamp,
)
- finish_time = proto.Field(
+ finish_time: timestamp_pb2.Timestamp = proto.Field(
proto.MESSAGE,
number=3,
message=timestamp_pb2.Timestamp,
)
- tables = proto.MapField(
+ tables: MutableMapping[str, TableProgress] = proto.MapField(
proto.STRING,
proto.MESSAGE,
number=4,
@@ -501,17 +539,17 @@ class UpdateClusterMetadata(proto.Message):
completed successfully.
"""
- original_request = proto.Field(
+ original_request: gba_instance.Cluster = proto.Field(
proto.MESSAGE,
number=1,
message=gba_instance.Cluster,
)
- request_time = proto.Field(
+ request_time: timestamp_pb2.Timestamp = proto.Field(
proto.MESSAGE,
number=2,
message=timestamp_pb2.Timestamp,
)
- finish_time = proto.Field(
+ finish_time: timestamp_pb2.Timestamp = proto.Field(
proto.MESSAGE,
number=3,
message=timestamp_pb2.Timestamp,
@@ -534,17 +572,17 @@ class PartialUpdateClusterMetadata(proto.Message):
PartialUpdateCluster.
"""
- request_time = proto.Field(
+ request_time: timestamp_pb2.Timestamp = proto.Field(
proto.MESSAGE,
number=1,
message=timestamp_pb2.Timestamp,
)
- finish_time = proto.Field(
+ finish_time: timestamp_pb2.Timestamp = proto.Field(
proto.MESSAGE,
number=2,
message=timestamp_pb2.Timestamp,
)
- original_request = proto.Field(
+ original_request: "PartialUpdateClusterRequest" = proto.Field(
proto.MESSAGE,
number=3,
message="PartialUpdateClusterRequest",
@@ -564,12 +602,12 @@ class PartialUpdateClusterRequest(proto.Message):
should be replaced.
"""
- cluster = proto.Field(
+ cluster: gba_instance.Cluster = proto.Field(
proto.MESSAGE,
number=1,
message=gba_instance.Cluster,
)
- update_mask = proto.Field(
+ update_mask: field_mask_pb2.FieldMask = proto.Field(
proto.MESSAGE,
number=2,
message=field_mask_pb2.FieldMask,
@@ -597,20 +635,20 @@ class CreateAppProfileRequest(proto.Message):
the app profile.
"""
- parent = proto.Field(
+ parent: str = proto.Field(
proto.STRING,
number=1,
)
- app_profile_id = proto.Field(
+ app_profile_id: str = proto.Field(
proto.STRING,
number=2,
)
- app_profile = proto.Field(
+ app_profile: gba_instance.AppProfile = proto.Field(
proto.MESSAGE,
number=3,
message=gba_instance.AppProfile,
)
- ignore_warnings = proto.Field(
+ ignore_warnings: bool = proto.Field(
proto.BOOL,
number=4,
)
@@ -626,7 +664,7 @@ class GetAppProfileRequest(proto.Message):
``projects/{project}/instances/{instance}/appProfiles/{app_profile}``.
"""
- name = proto.Field(
+ name: str = proto.Field(
proto.STRING,
number=1,
)
@@ -659,15 +697,15 @@ class ListAppProfilesRequest(proto.Message):
call.
"""
- parent = proto.Field(
+ parent: str = proto.Field(
proto.STRING,
number=1,
)
- page_size = proto.Field(
+ page_size: int = proto.Field(
proto.INT32,
number=3,
)
- page_token = proto.Field(
+ page_token: str = proto.Field(
proto.STRING,
number=2,
)
@@ -677,13 +715,13 @@ class ListAppProfilesResponse(proto.Message):
r"""Response message for BigtableInstanceAdmin.ListAppProfiles.
Attributes:
- app_profiles (Sequence[google.cloud.bigtable_admin_v2.types.AppProfile]):
+ app_profiles (MutableSequence[google.cloud.bigtable_admin_v2.types.AppProfile]):
The list of requested app profiles.
next_page_token (str):
Set if not all app profiles could be returned in a single
response. Pass this value to ``page_token`` in another
request to get the next page of results.
- failed_locations (Sequence[str]):
+ failed_locations (MutableSequence[str]):
Locations from which AppProfile information could not be
retrieved, due to an outage or some other transient
condition. AppProfiles from these locations may be missing
@@ -695,16 +733,16 @@ class ListAppProfilesResponse(proto.Message):
def raw_page(self):
return self
- app_profiles = proto.RepeatedField(
+ app_profiles: MutableSequence[gba_instance.AppProfile] = proto.RepeatedField(
proto.MESSAGE,
number=1,
message=gba_instance.AppProfile,
)
- next_page_token = proto.Field(
+ next_page_token: str = proto.Field(
proto.STRING,
number=2,
)
- failed_locations = proto.RepeatedField(
+ failed_locations: MutableSequence[str] = proto.RepeatedField(
proto.STRING,
number=3,
)
@@ -726,17 +764,17 @@ class UpdateAppProfileRequest(proto.Message):
the app profile.
"""
- app_profile = proto.Field(
+ app_profile: gba_instance.AppProfile = proto.Field(
proto.MESSAGE,
number=1,
message=gba_instance.AppProfile,
)
- update_mask = proto.Field(
+ update_mask: field_mask_pb2.FieldMask = proto.Field(
proto.MESSAGE,
number=2,
message=field_mask_pb2.FieldMask,
)
- ignore_warnings = proto.Field(
+ ignore_warnings: bool = proto.Field(
proto.BOOL,
number=3,
)
@@ -755,11 +793,11 @@ class DeleteAppProfileRequest(proto.Message):
deleting the app profile.
"""
- name = proto.Field(
+ name: str = proto.Field(
proto.STRING,
number=1,
)
- ignore_warnings = proto.Field(
+ ignore_warnings: bool = proto.Field(
proto.BOOL,
number=2,
)
@@ -807,25 +845,25 @@ class ListHotTabletsRequest(proto.Message):
call.
"""
- parent = proto.Field(
+ parent: str = proto.Field(
proto.STRING,
number=1,
)
- start_time = proto.Field(
+ start_time: timestamp_pb2.Timestamp = proto.Field(
proto.MESSAGE,
number=2,
message=timestamp_pb2.Timestamp,
)
- end_time = proto.Field(
+ end_time: timestamp_pb2.Timestamp = proto.Field(
proto.MESSAGE,
number=3,
message=timestamp_pb2.Timestamp,
)
- page_size = proto.Field(
+ page_size: int = proto.Field(
proto.INT32,
number=4,
)
- page_token = proto.Field(
+ page_token: str = proto.Field(
proto.STRING,
number=5,
)
@@ -835,7 +873,7 @@ class ListHotTabletsResponse(proto.Message):
r"""Response message for BigtableInstanceAdmin.ListHotTablets.
Attributes:
- hot_tablets (Sequence[google.cloud.bigtable_admin_v2.types.HotTablet]):
+ hot_tablets (MutableSequence[google.cloud.bigtable_admin_v2.types.HotTablet]):
List of hot tablets in the tables of the
requested cluster that fall within the requested
time range. Hot tablets are ordered by node cpu
@@ -854,12 +892,470 @@ class ListHotTabletsResponse(proto.Message):
def raw_page(self):
return self
- hot_tablets = proto.RepeatedField(
+ hot_tablets: MutableSequence[gba_instance.HotTablet] = proto.RepeatedField(
proto.MESSAGE,
number=1,
message=gba_instance.HotTablet,
)
- next_page_token = proto.Field(
+ next_page_token: str = proto.Field(
+ proto.STRING,
+ number=2,
+ )
+
+
+class CreateLogicalViewRequest(proto.Message):
+ r"""Request message for BigtableInstanceAdmin.CreateLogicalView.
+
+ Attributes:
+ parent (str):
+ Required. The parent instance where this logical view will
+ be created. Format:
+ ``projects/{project}/instances/{instance}``.
+ logical_view_id (str):
+ Required. The ID to use for the logical view,
+ which will become the final component of the
+ logical view's resource name.
+ logical_view (google.cloud.bigtable_admin_v2.types.LogicalView):
+ Required. The logical view to create.
+ """
+
+ parent: str = proto.Field(
+ proto.STRING,
+ number=1,
+ )
+ logical_view_id: str = proto.Field(
+ proto.STRING,
+ number=2,
+ )
+ logical_view: gba_instance.LogicalView = proto.Field(
+ proto.MESSAGE,
+ number=3,
+ message=gba_instance.LogicalView,
+ )
+
+
+class CreateLogicalViewMetadata(proto.Message):
+ r"""The metadata for the Operation returned by CreateLogicalView.
+
+ Attributes:
+ original_request (google.cloud.bigtable_admin_v2.types.CreateLogicalViewRequest):
+ The request that prompted the initiation of
+ this CreateLogicalView operation.
+ start_time (google.protobuf.timestamp_pb2.Timestamp):
+ The time at which this operation started.
+ end_time (google.protobuf.timestamp_pb2.Timestamp):
+ If set, the time at which this operation
+ finished or was canceled.
+ """
+
+ original_request: "CreateLogicalViewRequest" = proto.Field(
+ proto.MESSAGE,
+ number=1,
+ message="CreateLogicalViewRequest",
+ )
+ start_time: timestamp_pb2.Timestamp = proto.Field(
+ proto.MESSAGE,
+ number=2,
+ message=timestamp_pb2.Timestamp,
+ )
+ end_time: timestamp_pb2.Timestamp = proto.Field(
+ proto.MESSAGE,
+ number=3,
+ message=timestamp_pb2.Timestamp,
+ )
+
+
+class GetLogicalViewRequest(proto.Message):
+ r"""Request message for BigtableInstanceAdmin.GetLogicalView.
+
+ Attributes:
+ name (str):
+ Required. The unique name of the requested logical view.
+ Values are of the form
+ ``projects/{project}/instances/{instance}/logicalViews/{logical_view}``.
+ """
+
+ name: str = proto.Field(
+ proto.STRING,
+ number=1,
+ )
+
+
+class ListLogicalViewsRequest(proto.Message):
+ r"""Request message for BigtableInstanceAdmin.ListLogicalViews.
+
+ Attributes:
+ parent (str):
+ Required. The unique name of the instance for which the list
+ of logical views is requested. Values are of the form
+ ``projects/{project}/instances/{instance}``.
+ page_size (int):
+ Optional. The maximum number of logical views
+ to return. The service may return fewer than
+ this value
+ page_token (str):
+ Optional. A page token, received from a previous
+ ``ListLogicalViews`` call. Provide this to retrieve the
+ subsequent page.
+
+ When paginating, all other parameters provided to
+ ``ListLogicalViews`` must match the call that provided the
+ page token.
+ """
+
+ parent: str = proto.Field(
+ proto.STRING,
+ number=1,
+ )
+ page_size: int = proto.Field(
+ proto.INT32,
+ number=2,
+ )
+ page_token: str = proto.Field(
+ proto.STRING,
+ number=3,
+ )
+
+
+class ListLogicalViewsResponse(proto.Message):
+ r"""Response message for BigtableInstanceAdmin.ListLogicalViews.
+
+ Attributes:
+ logical_views (MutableSequence[google.cloud.bigtable_admin_v2.types.LogicalView]):
+ The list of requested logical views.
+ next_page_token (str):
+ A token, which can be sent as ``page_token`` to retrieve the
+ next page. If this field is omitted, there are no subsequent
+ pages.
+ """
+
+ @property
+ def raw_page(self):
+ return self
+
+ logical_views: MutableSequence[gba_instance.LogicalView] = proto.RepeatedField(
+ proto.MESSAGE,
+ number=1,
+ message=gba_instance.LogicalView,
+ )
+ next_page_token: str = proto.Field(
+ proto.STRING,
+ number=2,
+ )
+
+
+class UpdateLogicalViewRequest(proto.Message):
+ r"""Request message for BigtableInstanceAdmin.UpdateLogicalView.
+
+ Attributes:
+ logical_view (google.cloud.bigtable_admin_v2.types.LogicalView):
+ Required. The logical view to update.
+
+ The logical view's ``name`` field is used to identify the
+ view to update. Format:
+ ``projects/{project}/instances/{instance}/logicalViews/{logical_view}``.
+ update_mask (google.protobuf.field_mask_pb2.FieldMask):
+ Optional. The list of fields to update.
+ """
+
+ logical_view: gba_instance.LogicalView = proto.Field(
+ proto.MESSAGE,
+ number=1,
+ message=gba_instance.LogicalView,
+ )
+ update_mask: field_mask_pb2.FieldMask = proto.Field(
+ proto.MESSAGE,
+ number=2,
+ message=field_mask_pb2.FieldMask,
+ )
+
+
+class UpdateLogicalViewMetadata(proto.Message):
+ r"""The metadata for the Operation returned by UpdateLogicalView.
+
+ Attributes:
+ original_request (google.cloud.bigtable_admin_v2.types.UpdateLogicalViewRequest):
+ The request that prompted the initiation of
+ this UpdateLogicalView operation.
+ start_time (google.protobuf.timestamp_pb2.Timestamp):
+ The time at which this operation was started.
+ end_time (google.protobuf.timestamp_pb2.Timestamp):
+ If set, the time at which this operation
+ finished or was canceled.
+ """
+
+ original_request: "UpdateLogicalViewRequest" = proto.Field(
+ proto.MESSAGE,
+ number=1,
+ message="UpdateLogicalViewRequest",
+ )
+ start_time: timestamp_pb2.Timestamp = proto.Field(
+ proto.MESSAGE,
+ number=2,
+ message=timestamp_pb2.Timestamp,
+ )
+ end_time: timestamp_pb2.Timestamp = proto.Field(
+ proto.MESSAGE,
+ number=3,
+ message=timestamp_pb2.Timestamp,
+ )
+
+
+class DeleteLogicalViewRequest(proto.Message):
+ r"""Request message for BigtableInstanceAdmin.DeleteLogicalView.
+
+ Attributes:
+ name (str):
+ Required. The unique name of the logical view to be deleted.
+ Format:
+ ``projects/{project}/instances/{instance}/logicalViews/{logical_view}``.
+ etag (str):
+ Optional. The current etag of the logical
+ view. If an etag is provided and does not match
+ the current etag of the logical view, deletion
+ will be blocked and an ABORTED error will be
+ returned.
+ """
+
+ name: str = proto.Field(
+ proto.STRING,
+ number=1,
+ )
+ etag: str = proto.Field(
+ proto.STRING,
+ number=2,
+ )
+
+
+class CreateMaterializedViewRequest(proto.Message):
+ r"""Request message for
+ BigtableInstanceAdmin.CreateMaterializedView.
+
+ Attributes:
+ parent (str):
+ Required. The parent instance where this materialized view
+ will be created. Format:
+ ``projects/{project}/instances/{instance}``.
+ materialized_view_id (str):
+ Required. The ID to use for the materialized
+ view, which will become the final component of
+ the materialized view's resource name.
+ materialized_view (google.cloud.bigtable_admin_v2.types.MaterializedView):
+ Required. The materialized view to create.
+ """
+
+ parent: str = proto.Field(
+ proto.STRING,
+ number=1,
+ )
+ materialized_view_id: str = proto.Field(
+ proto.STRING,
+ number=2,
+ )
+ materialized_view: gba_instance.MaterializedView = proto.Field(
+ proto.MESSAGE,
+ number=3,
+ message=gba_instance.MaterializedView,
+ )
+
+
+class CreateMaterializedViewMetadata(proto.Message):
+ r"""The metadata for the Operation returned by
+ CreateMaterializedView.
+
+ Attributes:
+ original_request (google.cloud.bigtable_admin_v2.types.CreateMaterializedViewRequest):
+ The request that prompted the initiation of
+ this CreateMaterializedView operation.
+ start_time (google.protobuf.timestamp_pb2.Timestamp):
+ The time at which this operation started.
+ end_time (google.protobuf.timestamp_pb2.Timestamp):
+ If set, the time at which this operation
+ finished or was canceled.
+ """
+
+ original_request: "CreateMaterializedViewRequest" = proto.Field(
+ proto.MESSAGE,
+ number=1,
+ message="CreateMaterializedViewRequest",
+ )
+ start_time: timestamp_pb2.Timestamp = proto.Field(
+ proto.MESSAGE,
+ number=2,
+ message=timestamp_pb2.Timestamp,
+ )
+ end_time: timestamp_pb2.Timestamp = proto.Field(
+ proto.MESSAGE,
+ number=3,
+ message=timestamp_pb2.Timestamp,
+ )
+
+
+class GetMaterializedViewRequest(proto.Message):
+ r"""Request message for
+ BigtableInstanceAdmin.GetMaterializedView.
+
+ Attributes:
+ name (str):
+ Required. The unique name of the requested materialized
+ view. Values are of the form
+ ``projects/{project}/instances/{instance}/materializedViews/{materialized_view}``.
+ """
+
+ name: str = proto.Field(
+ proto.STRING,
+ number=1,
+ )
+
+
+class ListMaterializedViewsRequest(proto.Message):
+ r"""Request message for
+ BigtableInstanceAdmin.ListMaterializedViews.
+
+ Attributes:
+ parent (str):
+ Required. The unique name of the instance for which the list
+ of materialized views is requested. Values are of the form
+ ``projects/{project}/instances/{instance}``.
+ page_size (int):
+ Optional. The maximum number of materialized
+ views to return. The service may return fewer
+ than this value
+ page_token (str):
+ Optional. A page token, received from a previous
+ ``ListMaterializedViews`` call. Provide this to retrieve the
+ subsequent page.
+
+ When paginating, all other parameters provided to
+ ``ListMaterializedViews`` must match the call that provided
+ the page token.
+ """
+
+ parent: str = proto.Field(
+ proto.STRING,
+ number=1,
+ )
+ page_size: int = proto.Field(
+ proto.INT32,
+ number=2,
+ )
+ page_token: str = proto.Field(
+ proto.STRING,
+ number=3,
+ )
+
+
+class ListMaterializedViewsResponse(proto.Message):
+ r"""Response message for
+ BigtableInstanceAdmin.ListMaterializedViews.
+
+ Attributes:
+ materialized_views (MutableSequence[google.cloud.bigtable_admin_v2.types.MaterializedView]):
+ The list of requested materialized views.
+ next_page_token (str):
+ A token, which can be sent as ``page_token`` to retrieve the
+ next page. If this field is omitted, there are no subsequent
+ pages.
+ """
+
+ @property
+ def raw_page(self):
+ return self
+
+ materialized_views: MutableSequence[
+ gba_instance.MaterializedView
+ ] = proto.RepeatedField(
+ proto.MESSAGE,
+ number=1,
+ message=gba_instance.MaterializedView,
+ )
+ next_page_token: str = proto.Field(
+ proto.STRING,
+ number=2,
+ )
+
+
+class UpdateMaterializedViewRequest(proto.Message):
+ r"""Request message for
+ BigtableInstanceAdmin.UpdateMaterializedView.
+
+ Attributes:
+ materialized_view (google.cloud.bigtable_admin_v2.types.MaterializedView):
+ Required. The materialized view to update.
+
+ The materialized view's ``name`` field is used to identify
+ the view to update. Format:
+ ``projects/{project}/instances/{instance}/materializedViews/{materialized_view}``.
+ update_mask (google.protobuf.field_mask_pb2.FieldMask):
+ Optional. The list of fields to update.
+ """
+
+ materialized_view: gba_instance.MaterializedView = proto.Field(
+ proto.MESSAGE,
+ number=1,
+ message=gba_instance.MaterializedView,
+ )
+ update_mask: field_mask_pb2.FieldMask = proto.Field(
+ proto.MESSAGE,
+ number=2,
+ message=field_mask_pb2.FieldMask,
+ )
+
+
+class UpdateMaterializedViewMetadata(proto.Message):
+ r"""The metadata for the Operation returned by
+ UpdateMaterializedView.
+
+ Attributes:
+ original_request (google.cloud.bigtable_admin_v2.types.UpdateMaterializedViewRequest):
+ The request that prompted the initiation of
+ this UpdateMaterializedView operation.
+ start_time (google.protobuf.timestamp_pb2.Timestamp):
+ The time at which this operation was started.
+ end_time (google.protobuf.timestamp_pb2.Timestamp):
+ If set, the time at which this operation
+ finished or was canceled.
+ """
+
+ original_request: "UpdateMaterializedViewRequest" = proto.Field(
+ proto.MESSAGE,
+ number=1,
+ message="UpdateMaterializedViewRequest",
+ )
+ start_time: timestamp_pb2.Timestamp = proto.Field(
+ proto.MESSAGE,
+ number=2,
+ message=timestamp_pb2.Timestamp,
+ )
+ end_time: timestamp_pb2.Timestamp = proto.Field(
+ proto.MESSAGE,
+ number=3,
+ message=timestamp_pb2.Timestamp,
+ )
+
+
+class DeleteMaterializedViewRequest(proto.Message):
+ r"""Request message for
+ BigtableInstanceAdmin.DeleteMaterializedView.
+
+ Attributes:
+ name (str):
+ Required. The unique name of the materialized view to be
+ deleted. Format:
+ ``projects/{project}/instances/{instance}/materializedViews/{materialized_view}``.
+ etag (str):
+ Optional. The current etag of the
+ materialized view. If an etag is provided and
+ does not match the current etag of the
+ materialized view, deletion will be blocked and
+ an ABORTED error will be returned.
+ """
+
+ name: str = proto.Field(
+ proto.STRING,
+ number=1,
+ )
+ etag: str = proto.Field(
proto.STRING,
number=2,
)
diff --git a/google/cloud/bigtable_admin_v2/types/bigtable_table_admin.py b/google/cloud/bigtable_admin_v2/types/bigtable_table_admin.py
index 6a366a5e4..69de07a2a 100644
--- a/google/cloud/bigtable_admin_v2/types/bigtable_table_admin.py
+++ b/google/cloud/bigtable_admin_v2/types/bigtable_table_admin.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -13,6 +13,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+from __future__ import annotations
+
+from typing import MutableMapping, MutableSequence
+
import proto # type: ignore
from google.cloud.bigtable_admin_v2.types import common
@@ -34,11 +38,17 @@
"ListTablesRequest",
"ListTablesResponse",
"GetTableRequest",
+ "UpdateTableRequest",
+ "UpdateTableMetadata",
"DeleteTableRequest",
+ "UndeleteTableRequest",
+ "UndeleteTableMetadata",
"ModifyColumnFamiliesRequest",
"GenerateConsistencyTokenRequest",
"GenerateConsistencyTokenResponse",
"CheckConsistencyRequest",
+ "StandardReadRemoteWrites",
+ "DataBoostReadLocalWrites",
"CheckConsistencyResponse",
"SnapshotTableRequest",
"GetSnapshotRequest",
@@ -54,6 +64,24 @@
"DeleteBackupRequest",
"ListBackupsRequest",
"ListBackupsResponse",
+ "CopyBackupRequest",
+ "CopyBackupMetadata",
+ "CreateAuthorizedViewRequest",
+ "CreateAuthorizedViewMetadata",
+ "ListAuthorizedViewsRequest",
+ "ListAuthorizedViewsResponse",
+ "GetAuthorizedViewRequest",
+ "UpdateAuthorizedViewRequest",
+ "UpdateAuthorizedViewMetadata",
+ "DeleteAuthorizedViewRequest",
+ "CreateSchemaBundleRequest",
+ "CreateSchemaBundleMetadata",
+ "UpdateSchemaBundleRequest",
+ "UpdateSchemaBundleMetadata",
+ "GetSchemaBundleRequest",
+ "ListSchemaBundlesRequest",
+ "ListSchemaBundlesResponse",
+ "DeleteSchemaBundleRequest",
},
)
@@ -68,8 +96,7 @@ class RestoreTableRequest(proto.Message):
Attributes:
parent (str):
Required. The name of the instance in which to create the
- restored table. This instance must be in the same project as
- the source backup. Values are of the form
+ restored table. Values are of the form
``projects//instances/``.
table_id (str):
Required. The id of the table to create and restore to. This
@@ -84,15 +111,15 @@ class RestoreTableRequest(proto.Message):
This field is a member of `oneof`_ ``source``.
"""
- parent = proto.Field(
+ parent: str = proto.Field(
proto.STRING,
number=1,
)
- table_id = proto.Field(
+ table_id: str = proto.Field(
proto.STRING,
number=2,
)
- backup = proto.Field(
+ backup: str = proto.Field(
proto.STRING,
number=3,
oneof="source",
@@ -132,26 +159,26 @@ class RestoreTableMetadata(proto.Message):
operation.
"""
- name = proto.Field(
+ name: str = proto.Field(
proto.STRING,
number=1,
)
- source_type = proto.Field(
+ source_type: gba_table.RestoreSourceType = proto.Field(
proto.ENUM,
number=2,
enum=gba_table.RestoreSourceType,
)
- backup_info = proto.Field(
+ backup_info: gba_table.BackupInfo = proto.Field(
proto.MESSAGE,
number=3,
oneof="source_info",
message=gba_table.BackupInfo,
)
- optimize_table_operation_name = proto.Field(
+ optimize_table_operation_name: str = proto.Field(
proto.STRING,
number=4,
)
- progress = proto.Field(
+ progress: common.OperationProgress = proto.Field(
proto.MESSAGE,
number=5,
message=common.OperationProgress,
@@ -173,11 +200,11 @@ class OptimizeRestoredTableMetadata(proto.Message):
optimizations.
"""
- name = proto.Field(
+ name: str = proto.Field(
proto.STRING,
number=1,
)
- progress = proto.Field(
+ progress: common.OperationProgress = proto.Field(
proto.MESSAGE,
number=2,
message=common.OperationProgress,
@@ -199,7 +226,7 @@ class CreateTableRequest(proto.Message):
``{parent}/tables/foobar``. Maximum 50 characters.
table (google.cloud.bigtable_admin_v2.types.Table):
Required. The Table to create.
- initial_splits (Sequence[google.cloud.bigtable_admin_v2.types.CreateTableRequest.Split]):
+ initial_splits (MutableSequence[google.cloud.bigtable_admin_v2.types.CreateTableRequest.Split]):
The optional list of row keys that will be used to initially
split the table into several tablets (tablets are similar to
HBase regions). Given two split keys, ``s1`` and ``s2``,
@@ -208,20 +235,20 @@ class CreateTableRequest(proto.Message):
Example:
- - Row keys :=
- ``["a", "apple", "custom", "customer_1", "customer_2",``
- ``"other", "zz"]``
- - initial_split_keys :=
- ``["apple", "customer_1", "customer_2", "other"]``
- - Key assignment:
-
- - Tablet 1 ``[, apple) => {"a"}.``
- - Tablet 2
- ``[apple, customer_1) => {"apple", "custom"}.``
- - Tablet 3
- ``[customer_1, customer_2) => {"customer_1"}.``
- - Tablet 4 ``[customer_2, other) => {"customer_2"}.``
- - Tablet 5 ``[other, ) => {"other", "zz"}.``
+ - Row keys :=
+ ``["a", "apple", "custom", "customer_1", "customer_2",``
+ ``"other", "zz"]``
+ - initial_split_keys :=
+ ``["apple", "customer_1", "customer_2", "other"]``
+ - Key assignment:
+
+ - Tablet 1 ``[, apple) => {"a"}.``
+ - Tablet 2
+ ``[apple, customer_1) => {"apple", "custom"}.``
+ - Tablet 3 ``[customer_1, customer_2) => {"customer_1"}.``
+ - Tablet 4 ``[customer_2, other) => {"customer_2"}.``
+ - Tablet 5
+ ``[other, ) => {"other", "zz"}.``
"""
class Split(proto.Message):
@@ -232,25 +259,25 @@ class Split(proto.Message):
Row key to use as an initial tablet boundary.
"""
- key = proto.Field(
+ key: bytes = proto.Field(
proto.BYTES,
number=1,
)
- parent = proto.Field(
+ parent: str = proto.Field(
proto.STRING,
number=1,
)
- table_id = proto.Field(
+ table_id: str = proto.Field(
proto.STRING,
number=2,
)
- table = proto.Field(
+ table: gba_table.Table = proto.Field(
proto.MESSAGE,
number=3,
message=gba_table.Table,
)
- initial_splits = proto.RepeatedField(
+ initial_splits: MutableSequence[Split] = proto.RepeatedField(
proto.MESSAGE,
number=4,
message=Split,
@@ -283,15 +310,15 @@ class CreateTableFromSnapshotRequest(proto.Message):
``projects/{project}/instances/{instance}/clusters/{cluster}/snapshots/{snapshot}``.
"""
- parent = proto.Field(
+ parent: str = proto.Field(
proto.STRING,
number=1,
)
- table_id = proto.Field(
+ table_id: str = proto.Field(
proto.STRING,
number=2,
)
- source_snapshot = proto.Field(
+ source_snapshot: str = proto.Field(
proto.STRING,
number=3,
)
@@ -325,16 +352,16 @@ class DropRowRangeRequest(proto.Message):
This field is a member of `oneof`_ ``target``.
"""
- name = proto.Field(
+ name: str = proto.Field(
proto.STRING,
number=1,
)
- row_key_prefix = proto.Field(
+ row_key_prefix: bytes = proto.Field(
proto.BYTES,
number=2,
oneof="target",
)
- delete_all_data_from_table = proto.Field(
+ delete_all_data_from_table: bool = proto.Field(
proto.BOOL,
number=3,
oneof="target",
@@ -351,7 +378,7 @@ class ListTablesRequest(proto.Message):
should be listed. Values are of the form
``projects/{project}/instances/{instance}``.
view (google.cloud.bigtable_admin_v2.types.Table.View):
- The view to be applied to the returned tables' fields. Only
+ The view to be applied to the returned tables' fields.
NAME_ONLY view (default) and REPLICATION_VIEW are supported.
page_size (int):
Maximum number of results per page.
@@ -370,20 +397,20 @@ class ListTablesRequest(proto.Message):
call.
"""
- parent = proto.Field(
+ parent: str = proto.Field(
proto.STRING,
number=1,
)
- view = proto.Field(
+ view: gba_table.Table.View = proto.Field(
proto.ENUM,
number=2,
enum=gba_table.Table.View,
)
- page_size = proto.Field(
+ page_size: int = proto.Field(
proto.INT32,
number=4,
)
- page_token = proto.Field(
+ page_token: str = proto.Field(
proto.STRING,
number=3,
)
@@ -394,7 +421,7 @@ class ListTablesResponse(proto.Message):
[google.bigtable.admin.v2.BigtableTableAdmin.ListTables][google.bigtable.admin.v2.BigtableTableAdmin.ListTables]
Attributes:
- tables (Sequence[google.cloud.bigtable_admin_v2.types.Table]):
+ tables (MutableSequence[google.cloud.bigtable_admin_v2.types.Table]):
The tables present in the requested instance.
next_page_token (str):
Set if not all tables could be returned in a single
@@ -406,12 +433,12 @@ class ListTablesResponse(proto.Message):
def raw_page(self):
return self
- tables = proto.RepeatedField(
+ tables: MutableSequence[gba_table.Table] = proto.RepeatedField(
proto.MESSAGE,
number=1,
message=gba_table.Table,
)
- next_page_token = proto.Field(
+ next_page_token: str = proto.Field(
proto.STRING,
number=2,
)
@@ -431,17 +458,91 @@ class GetTableRequest(proto.Message):
Defaults to ``SCHEMA_VIEW`` if unspecified.
"""
- name = proto.Field(
+ name: str = proto.Field(
proto.STRING,
number=1,
)
- view = proto.Field(
+ view: gba_table.Table.View = proto.Field(
proto.ENUM,
number=2,
enum=gba_table.Table.View,
)
+class UpdateTableRequest(proto.Message):
+ r"""The request for
+ [UpdateTable][google.bigtable.admin.v2.BigtableTableAdmin.UpdateTable].
+
+ Attributes:
+ table (google.cloud.bigtable_admin_v2.types.Table):
+ Required. The table to update. The table's ``name`` field is
+ used to identify the table to update.
+ update_mask (google.protobuf.field_mask_pb2.FieldMask):
+ Required. The list of fields to update. A mask specifying
+ which fields (e.g. ``change_stream_config``) in the
+ ``table`` field should be updated. This mask is relative to
+ the ``table`` field, not to the request message. The
+ wildcard (\*) path is currently not supported. Currently
+ UpdateTable is only supported for the following fields:
+
+ - ``change_stream_config``
+ - ``change_stream_config.retention_period``
+ - ``deletion_protection``
+ - ``row_key_schema``
+
+ If ``column_families`` is set in ``update_mask``, it will
+ return an UNIMPLEMENTED error.
+ ignore_warnings (bool):
+ Optional. If true, ignore safety checks when
+ updating the table.
+ """
+
+ table: gba_table.Table = proto.Field(
+ proto.MESSAGE,
+ number=1,
+ message=gba_table.Table,
+ )
+ update_mask: field_mask_pb2.FieldMask = proto.Field(
+ proto.MESSAGE,
+ number=2,
+ message=field_mask_pb2.FieldMask,
+ )
+ ignore_warnings: bool = proto.Field(
+ proto.BOOL,
+ number=3,
+ )
+
+
+class UpdateTableMetadata(proto.Message):
+ r"""Metadata type for the operation returned by
+ [UpdateTable][google.bigtable.admin.v2.BigtableTableAdmin.UpdateTable].
+
+ Attributes:
+ name (str):
+ The name of the table being updated.
+ start_time (google.protobuf.timestamp_pb2.Timestamp):
+ The time at which this operation started.
+ end_time (google.protobuf.timestamp_pb2.Timestamp):
+ If set, the time at which this operation
+ finished or was canceled.
+ """
+
+ name: str = proto.Field(
+ proto.STRING,
+ number=1,
+ )
+ start_time: timestamp_pb2.Timestamp = proto.Field(
+ proto.MESSAGE,
+ number=2,
+ message=timestamp_pb2.Timestamp,
+ )
+ end_time: timestamp_pb2.Timestamp = proto.Field(
+ proto.MESSAGE,
+ number=3,
+ message=timestamp_pb2.Timestamp,
+ )
+
+
class DeleteTableRequest(proto.Message):
r"""Request message for
[google.bigtable.admin.v2.BigtableTableAdmin.DeleteTable][google.bigtable.admin.v2.BigtableTableAdmin.DeleteTable]
@@ -453,10 +554,57 @@ class DeleteTableRequest(proto.Message):
``projects/{project}/instances/{instance}/tables/{table}``.
"""
- name = proto.Field(
+ name: str = proto.Field(
+ proto.STRING,
+ number=1,
+ )
+
+
+class UndeleteTableRequest(proto.Message):
+ r"""Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.UndeleteTable][google.bigtable.admin.v2.BigtableTableAdmin.UndeleteTable]
+
+ Attributes:
+ name (str):
+ Required. The unique name of the table to be restored.
+ Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}``.
+ """
+
+ name: str = proto.Field(
+ proto.STRING,
+ number=1,
+ )
+
+
+class UndeleteTableMetadata(proto.Message):
+ r"""Metadata type for the operation returned by
+ [google.bigtable.admin.v2.BigtableTableAdmin.UndeleteTable][google.bigtable.admin.v2.BigtableTableAdmin.UndeleteTable].
+
+ Attributes:
+ name (str):
+ The name of the table being restored.
+ start_time (google.protobuf.timestamp_pb2.Timestamp):
+ The time at which this operation started.
+ end_time (google.protobuf.timestamp_pb2.Timestamp):
+ If set, the time at which this operation
+ finished or was cancelled.
+ """
+
+ name: str = proto.Field(
proto.STRING,
number=1,
)
+ start_time: timestamp_pb2.Timestamp = proto.Field(
+ proto.MESSAGE,
+ number=2,
+ message=timestamp_pb2.Timestamp,
+ )
+ end_time: timestamp_pb2.Timestamp = proto.Field(
+ proto.MESSAGE,
+ number=3,
+ message=timestamp_pb2.Timestamp,
+ )
class ModifyColumnFamiliesRequest(proto.Message):
@@ -468,13 +616,16 @@ class ModifyColumnFamiliesRequest(proto.Message):
Required. The unique name of the table whose families should
be modified. Values are of the form
``projects/{project}/instances/{instance}/tables/{table}``.
- modifications (Sequence[google.cloud.bigtable_admin_v2.types.ModifyColumnFamiliesRequest.Modification]):
+ modifications (MutableSequence[google.cloud.bigtable_admin_v2.types.ModifyColumnFamiliesRequest.Modification]):
Required. Modifications to be atomically
applied to the specified table's families.
Entries are applied in order, meaning that
earlier modifications can be masked by later
ones (in the case of repeated updates to the
same family, for example).
+ ignore_warnings (bool):
+ Optional. If true, ignore safety checks when
+ modifying the column families.
"""
class Modification(proto.Message):
@@ -507,39 +658,53 @@ class Modification(proto.Message):
given ID, or fail if no such family exists.
This field is a member of `oneof`_ ``mod``.
+ update_mask (google.protobuf.field_mask_pb2.FieldMask):
+ Optional. A mask specifying which fields (e.g. ``gc_rule``)
+ in the ``update`` mod should be updated, ignored for other
+ modification types. If unset or empty, we treat it as
+ updating ``gc_rule`` to be backward compatible.
"""
- id = proto.Field(
+ id: str = proto.Field(
proto.STRING,
number=1,
)
- create = proto.Field(
+ create: gba_table.ColumnFamily = proto.Field(
proto.MESSAGE,
number=2,
oneof="mod",
message=gba_table.ColumnFamily,
)
- update = proto.Field(
+ update: gba_table.ColumnFamily = proto.Field(
proto.MESSAGE,
number=3,
oneof="mod",
message=gba_table.ColumnFamily,
)
- drop = proto.Field(
+ drop: bool = proto.Field(
proto.BOOL,
number=4,
oneof="mod",
)
+ update_mask: field_mask_pb2.FieldMask = proto.Field(
+ proto.MESSAGE,
+ number=6,
+ message=field_mask_pb2.FieldMask,
+ )
- name = proto.Field(
+ name: str = proto.Field(
proto.STRING,
number=1,
)
- modifications = proto.RepeatedField(
+ modifications: MutableSequence[Modification] = proto.RepeatedField(
proto.MESSAGE,
number=2,
message=Modification,
)
+ ignore_warnings: bool = proto.Field(
+ proto.BOOL,
+ number=3,
+ )
class GenerateConsistencyTokenRequest(proto.Message):
@@ -553,7 +718,7 @@ class GenerateConsistencyTokenRequest(proto.Message):
``projects/{project}/instances/{instance}/tables/{table}``.
"""
- name = proto.Field(
+ name: str = proto.Field(
proto.STRING,
number=1,
)
@@ -568,7 +733,7 @@ class GenerateConsistencyTokenResponse(proto.Message):
The generated consistency token.
"""
- consistency_token = proto.Field(
+ consistency_token: str = proto.Field(
proto.STRING,
number=1,
)
@@ -578,6 +743,13 @@ class CheckConsistencyRequest(proto.Message):
r"""Request message for
[google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency][google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency]
+ This message has `oneof`_ fields (mutually exclusive fields).
+ For each oneof, at most one member field can be set at the same time.
+ Setting any member of the oneof automatically clears all other
+ members.
+
+ .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields
+
Attributes:
name (str):
Required. The unique name of the Table for which to check
@@ -586,16 +758,56 @@ class CheckConsistencyRequest(proto.Message):
consistency_token (str):
Required. The token created using
GenerateConsistencyToken for the Table.
+ standard_read_remote_writes (google.cloud.bigtable_admin_v2.types.StandardReadRemoteWrites):
+ Checks that reads using an app profile with
+ ``StandardIsolation`` can see all writes committed before
+ the token was created, even if the read and write target
+ different clusters.
+
+ This field is a member of `oneof`_ ``mode``.
+ data_boost_read_local_writes (google.cloud.bigtable_admin_v2.types.DataBoostReadLocalWrites):
+ Checks that reads using an app profile with
+ ``DataBoostIsolationReadOnly`` can see all writes committed
+ before the token was created, but only if the read and write
+ target the same cluster.
+
+ This field is a member of `oneof`_ ``mode``.
"""
- name = proto.Field(
+ name: str = proto.Field(
proto.STRING,
number=1,
)
- consistency_token = proto.Field(
+ consistency_token: str = proto.Field(
proto.STRING,
number=2,
)
+ standard_read_remote_writes: "StandardReadRemoteWrites" = proto.Field(
+ proto.MESSAGE,
+ number=3,
+ oneof="mode",
+ message="StandardReadRemoteWrites",
+ )
+ data_boost_read_local_writes: "DataBoostReadLocalWrites" = proto.Field(
+ proto.MESSAGE,
+ number=4,
+ oneof="mode",
+ message="DataBoostReadLocalWrites",
+ )
+
+
+class StandardReadRemoteWrites(proto.Message):
+ r"""Checks that all writes before the consistency token was
+ generated are replicated in every cluster and readable.
+
+ """
+
+
+class DataBoostReadLocalWrites(proto.Message):
+ r"""Checks that all writes before the consistency token was
+ generated in the same cluster are readable by Databoost.
+
+ """
class CheckConsistencyResponse(proto.Message):
@@ -609,7 +821,7 @@ class CheckConsistencyResponse(proto.Message):
the restrictions specified in the request.
"""
- consistent = proto.Field(
+ consistent: bool = proto.Field(
proto.BOOL,
number=1,
)
@@ -650,24 +862,24 @@ class SnapshotTableRequest(proto.Message):
Description of the snapshot.
"""
- name = proto.Field(
+ name: str = proto.Field(
proto.STRING,
number=1,
)
- cluster = proto.Field(
+ cluster: str = proto.Field(
proto.STRING,
number=2,
)
- snapshot_id = proto.Field(
+ snapshot_id: str = proto.Field(
proto.STRING,
number=3,
)
- ttl = proto.Field(
+ ttl: duration_pb2.Duration = proto.Field(
proto.MESSAGE,
number=4,
message=duration_pb2.Duration,
)
- description = proto.Field(
+ description: str = proto.Field(
proto.STRING,
number=5,
)
@@ -690,7 +902,7 @@ class GetSnapshotRequest(proto.Message):
``projects/{project}/instances/{instance}/clusters/{cluster}/snapshots/{snapshot}``.
"""
- name = proto.Field(
+ name: str = proto.Field(
proto.STRING,
number=1,
)
@@ -722,15 +934,15 @@ class ListSnapshotsRequest(proto.Message):
call.
"""
- parent = proto.Field(
+ parent: str = proto.Field(
proto.STRING,
number=1,
)
- page_size = proto.Field(
+ page_size: int = proto.Field(
proto.INT32,
number=2,
)
- page_token = proto.Field(
+ page_token: str = proto.Field(
proto.STRING,
number=3,
)
@@ -747,7 +959,7 @@ class ListSnapshotsResponse(proto.Message):
any SLA or deprecation policy.
Attributes:
- snapshots (Sequence[google.cloud.bigtable_admin_v2.types.Snapshot]):
+ snapshots (MutableSequence[google.cloud.bigtable_admin_v2.types.Snapshot]):
The snapshots present in the requested
cluster.
next_page_token (str):
@@ -760,12 +972,12 @@ class ListSnapshotsResponse(proto.Message):
def raw_page(self):
return self
- snapshots = proto.RepeatedField(
+ snapshots: MutableSequence[gba_table.Snapshot] = proto.RepeatedField(
proto.MESSAGE,
number=1,
message=gba_table.Snapshot,
)
- next_page_token = proto.Field(
+ next_page_token: str = proto.Field(
proto.STRING,
number=2,
)
@@ -788,7 +1000,7 @@ class DeleteSnapshotRequest(proto.Message):
``projects/{project}/instances/{instance}/clusters/{cluster}/snapshots/{snapshot}``.
"""
- name = proto.Field(
+ name: str = proto.Field(
proto.STRING,
number=1,
)
@@ -796,6 +1008,7 @@ class DeleteSnapshotRequest(proto.Message):
class SnapshotTableMetadata(proto.Message):
r"""The metadata for the Operation returned by SnapshotTable.
+
Note: This is a private alpha release of Cloud Bigtable
snapshots. This feature is not currently available to most Cloud
Bigtable customers. This feature might be changed in
@@ -814,17 +1027,17 @@ class SnapshotTableMetadata(proto.Message):
completed successfully.
"""
- original_request = proto.Field(
+ original_request: "SnapshotTableRequest" = proto.Field(
proto.MESSAGE,
number=1,
message="SnapshotTableRequest",
)
- request_time = proto.Field(
+ request_time: timestamp_pb2.Timestamp = proto.Field(
proto.MESSAGE,
number=2,
message=timestamp_pb2.Timestamp,
)
- finish_time = proto.Field(
+ finish_time: timestamp_pb2.Timestamp = proto.Field(
proto.MESSAGE,
number=3,
message=timestamp_pb2.Timestamp,
@@ -852,17 +1065,17 @@ class CreateTableFromSnapshotMetadata(proto.Message):
completed successfully.
"""
- original_request = proto.Field(
+ original_request: "CreateTableFromSnapshotRequest" = proto.Field(
proto.MESSAGE,
number=1,
message="CreateTableFromSnapshotRequest",
)
- request_time = proto.Field(
+ request_time: timestamp_pb2.Timestamp = proto.Field(
proto.MESSAGE,
number=2,
message=timestamp_pb2.Timestamp,
)
- finish_time = proto.Field(
+ finish_time: timestamp_pb2.Timestamp = proto.Field(
proto.MESSAGE,
number=3,
message=timestamp_pb2.Timestamp,
@@ -886,20 +1099,20 @@ class CreateBackupRequest(proto.Message):
name, of the form:
``projects/{project}/instances/{instance}/clusters/{cluster}/backups/{backup_id}``.
This string must be between 1 and 50 characters in length
- and match the regex [*a-zA-Z0-9][-*.a-zA-Z0-9]*.
+ and match the regex [*a-zA-Z0-9][-*.a-zA-Z0-9]\*.
backup (google.cloud.bigtable_admin_v2.types.Backup):
Required. The backup to create.
"""
- parent = proto.Field(
+ parent: str = proto.Field(
proto.STRING,
number=1,
)
- backup_id = proto.Field(
+ backup_id: str = proto.Field(
proto.STRING,
number=2,
)
- backup = proto.Field(
+ backup: gba_table.Backup = proto.Field(
proto.MESSAGE,
number=3,
message=gba_table.Backup,
@@ -923,20 +1136,20 @@ class CreateBackupMetadata(proto.Message):
finished or was cancelled.
"""
- name = proto.Field(
+ name: str = proto.Field(
proto.STRING,
number=1,
)
- source_table = proto.Field(
+ source_table: str = proto.Field(
proto.STRING,
number=2,
)
- start_time = proto.Field(
+ start_time: timestamp_pb2.Timestamp = proto.Field(
proto.MESSAGE,
number=3,
message=timestamp_pb2.Timestamp,
)
- end_time = proto.Field(
+ end_time: timestamp_pb2.Timestamp = proto.Field(
proto.MESSAGE,
number=4,
message=timestamp_pb2.Timestamp,
@@ -954,7 +1167,7 @@ class UpdateBackupRequest(proto.Message):
required. Other fields are ignored. Update is only supported
for the following fields:
- - ``backup.expire_time``.
+ - ``backup.expire_time``.
update_mask (google.protobuf.field_mask_pb2.FieldMask):
Required. A mask specifying which fields (e.g.
``expire_time``) in the Backup resource should be updated.
@@ -964,12 +1177,12 @@ class UpdateBackupRequest(proto.Message):
accidentally by clients that do not know about them.
"""
- backup = proto.Field(
+ backup: gba_table.Backup = proto.Field(
proto.MESSAGE,
number=1,
message=gba_table.Backup,
)
- update_mask = proto.Field(
+ update_mask: field_mask_pb2.FieldMask = proto.Field(
proto.MESSAGE,
number=2,
message=field_mask_pb2.FieldMask,
@@ -986,7 +1199,7 @@ class GetBackupRequest(proto.Message):
``projects/{project}/instances/{instance}/clusters/{cluster}/backups/{backup}``.
"""
- name = proto.Field(
+ name: str = proto.Field(
proto.STRING,
number=1,
)
@@ -1003,7 +1216,7 @@ class DeleteBackupRequest(proto.Message):
``projects/{project}/instances/{instance}/clusters/{cluster}/backups/{backup}``.
"""
- name = proto.Field(
+ name: str = proto.Field(
proto.STRING,
number=1,
)
@@ -1033,16 +1246,16 @@ class ListBackupsRequest(proto.Message):
The fields eligible for filtering are:
- - ``name``
- - ``source_table``
- - ``state``
- - ``start_time`` (and values are of the format
- YYYY-MM-DDTHH:MM:SSZ)
- - ``end_time`` (and values are of the format
- YYYY-MM-DDTHH:MM:SSZ)
- - ``expire_time`` (and values are of the format
- YYYY-MM-DDTHH:MM:SSZ)
- - ``size_bytes``
+ - ``name``
+ - ``source_table``
+ - ``state``
+ - ``start_time`` (and values are of the format
+ YYYY-MM-DDTHH:MM:SSZ)
+ - ``end_time`` (and values are of the format
+ YYYY-MM-DDTHH:MM:SSZ)
+ - ``expire_time`` (and values are of the format
+ YYYY-MM-DDTHH:MM:SSZ)
+ - ``size_bytes``
To filter on multiple expressions, provide each separate
expression within parentheses. By default, each expression
@@ -1051,28 +1264,35 @@ class ListBackupsRequest(proto.Message):
Some examples of using filters are:
- - ``name:"exact"`` --> The backup's name is the string
- "exact".
- - ``name:howl`` --> The backup's name contains the string
- "howl".
- - ``source_table:prod`` --> The source_table's name
- contains the string "prod".
- - ``state:CREATING`` --> The backup is pending creation.
- - ``state:READY`` --> The backup is fully created and ready
- for use.
- - ``(name:howl) AND (start_time < \"2018-03-28T14:50:00Z\")``
- --> The backup name contains the string "howl" and
- start_time of the backup is before 2018-03-28T14:50:00Z.
- - ``size_bytes > 10000000000`` --> The backup's size is
- greater than 10GB
+ - ``name:"exact"`` --> The backup's name is the string
+ "exact".
+ - ``name:howl`` --> The backup's name contains the string
+ "howl".
+ - ``source_table:prod`` --> The source_table's name contains
+ the string "prod".
+ - ``state:CREATING`` --> The backup is pending creation.
+ - ``state:READY`` --> The backup is fully created and ready
+ for use.
+ - ``(name:howl) AND (start_time < \"2018-03-28T14:50:00Z\")``
+ --> The backup name contains the string "howl" and
+ start_time of the backup is before 2018-03-28T14:50:00Z.
+ - ``size_bytes > 10000000000`` --> The backup's size is
+ greater than 10GB
order_by (str):
An expression for specifying the sort order of the results
of the request. The string value should specify one or more
fields in [Backup][google.bigtable.admin.v2.Backup]. The
full syntax is described at https://aip.dev/132#ordering.
- Fields supported are: \* name \* source_table \* expire_time
- \* start_time \* end_time \* size_bytes \* state
+ Fields supported are:
+
+ - name
+ - source_table
+ - expire_time
+ - start_time
+ - end_time
+ - size_bytes
+ - state
For example, "start_time". The default sorting order is
ascending. To specify descending order for the field, a
@@ -1095,23 +1315,23 @@ class ListBackupsRequest(proto.Message):
to the same ``parent`` and with the same ``filter``.
"""
- parent = proto.Field(
+ parent: str = proto.Field(
proto.STRING,
number=1,
)
- filter = proto.Field(
+ filter: str = proto.Field(
proto.STRING,
number=2,
)
- order_by = proto.Field(
+ order_by: str = proto.Field(
proto.STRING,
number=3,
)
- page_size = proto.Field(
+ page_size: int = proto.Field(
proto.INT32,
number=4,
)
- page_token = proto.Field(
+ page_token: str = proto.Field(
proto.STRING,
number=5,
)
@@ -1122,7 +1342,7 @@ class ListBackupsResponse(proto.Message):
[ListBackups][google.bigtable.admin.v2.BigtableTableAdmin.ListBackups].
Attributes:
- backups (Sequence[google.cloud.bigtable_admin_v2.types.Backup]):
+ backups (MutableSequence[google.cloud.bigtable_admin_v2.types.Backup]):
The list of matching backups.
next_page_token (str):
``next_page_token`` can be sent in a subsequent
@@ -1134,12 +1354,610 @@ class ListBackupsResponse(proto.Message):
def raw_page(self):
return self
- backups = proto.RepeatedField(
+ backups: MutableSequence[gba_table.Backup] = proto.RepeatedField(
proto.MESSAGE,
number=1,
message=gba_table.Backup,
)
- next_page_token = proto.Field(
+ next_page_token: str = proto.Field(
+ proto.STRING,
+ number=2,
+ )
+
+
+class CopyBackupRequest(proto.Message):
+ r"""The request for
+ [CopyBackup][google.bigtable.admin.v2.BigtableTableAdmin.CopyBackup].
+
+ Attributes:
+ parent (str):
+ Required. The name of the destination cluster that will
+ contain the backup copy. The cluster must already exist.
+ Values are of the form:
+ ``projects/{project}/instances/{instance}/clusters/{cluster}``.
+ backup_id (str):
+ Required. The id of the new backup. The ``backup_id`` along
+ with ``parent`` are combined as {parent}/backups/{backup_id}
+ to create the full backup name, of the form:
+ ``projects/{project}/instances/{instance}/clusters/{cluster}/backups/{backup_id}``.
+ This string must be between 1 and 50 characters in length
+ and match the regex [*a-zA-Z0-9][-*.a-zA-Z0-9]\*.
+ source_backup (str):
+ Required. The source backup to be copied from. The source
+ backup needs to be in READY state for it to be copied.
+ Copying a copied backup is not allowed. Once CopyBackup is
+ in progress, the source backup cannot be deleted or cleaned
+ up on expiration until CopyBackup is finished. Values are of
+ the form:
+ ``projects//instances//clusters//backups/``.
+ expire_time (google.protobuf.timestamp_pb2.Timestamp):
+ Required. Required. The expiration time of the copied backup
+ with microsecond granularity that must be at least 6 hours
+ and at most 30 days from the time the request is received.
+ Once the ``expire_time`` has passed, Cloud Bigtable will
+ delete the backup and free the resources used by the backup.
+ """
+
+ parent: str = proto.Field(
+ proto.STRING,
+ number=1,
+ )
+ backup_id: str = proto.Field(
+ proto.STRING,
+ number=2,
+ )
+ source_backup: str = proto.Field(
+ proto.STRING,
+ number=3,
+ )
+ expire_time: timestamp_pb2.Timestamp = proto.Field(
+ proto.MESSAGE,
+ number=4,
+ message=timestamp_pb2.Timestamp,
+ )
+
+
+class CopyBackupMetadata(proto.Message):
+ r"""Metadata type for the google.longrunning.Operation returned by
+ [CopyBackup][google.bigtable.admin.v2.BigtableTableAdmin.CopyBackup].
+
+ Attributes:
+ name (str):
+ The name of the backup being created through the copy
+ operation. Values are of the form
+ ``projects//instances//clusters//backups/``.
+ source_backup_info (google.cloud.bigtable_admin_v2.types.BackupInfo):
+ Information about the source backup that is
+ being copied from.
+ progress (google.cloud.bigtable_admin_v2.types.OperationProgress):
+ The progress of the
+ [CopyBackup][google.bigtable.admin.v2.BigtableTableAdmin.CopyBackup]
+ operation.
+ """
+
+ name: str = proto.Field(
+ proto.STRING,
+ number=1,
+ )
+ source_backup_info: gba_table.BackupInfo = proto.Field(
+ proto.MESSAGE,
+ number=2,
+ message=gba_table.BackupInfo,
+ )
+ progress: common.OperationProgress = proto.Field(
+ proto.MESSAGE,
+ number=3,
+ message=common.OperationProgress,
+ )
+
+
+class CreateAuthorizedViewRequest(proto.Message):
+ r"""The request for
+ [CreateAuthorizedView][google.bigtable.admin.v2.BigtableTableAdmin.CreateAuthorizedView]
+
+ Attributes:
+ parent (str):
+ Required. This is the name of the table the AuthorizedView
+ belongs to. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}``.
+ authorized_view_id (str):
+ Required. The id of the AuthorizedView to create. This
+ AuthorizedView must not already exist. The
+ ``authorized_view_id`` appended to ``parent`` forms the full
+ AuthorizedView name of the form
+ ``projects/{project}/instances/{instance}/tables/{table}/authorizedView/{authorized_view}``.
+ authorized_view (google.cloud.bigtable_admin_v2.types.AuthorizedView):
+ Required. The AuthorizedView to create.
+ """
+
+ parent: str = proto.Field(
+ proto.STRING,
+ number=1,
+ )
+ authorized_view_id: str = proto.Field(
+ proto.STRING,
+ number=2,
+ )
+ authorized_view: gba_table.AuthorizedView = proto.Field(
+ proto.MESSAGE,
+ number=3,
+ message=gba_table.AuthorizedView,
+ )
+
+
+class CreateAuthorizedViewMetadata(proto.Message):
+ r"""The metadata for the Operation returned by
+ CreateAuthorizedView.
+
+ Attributes:
+ original_request (google.cloud.bigtable_admin_v2.types.CreateAuthorizedViewRequest):
+ The request that prompted the initiation of
+ this CreateAuthorizedView operation.
+ request_time (google.protobuf.timestamp_pb2.Timestamp):
+ The time at which the original request was
+ received.
+ finish_time (google.protobuf.timestamp_pb2.Timestamp):
+ The time at which the operation failed or was
+ completed successfully.
+ """
+
+ original_request: "CreateAuthorizedViewRequest" = proto.Field(
+ proto.MESSAGE,
+ number=1,
+ message="CreateAuthorizedViewRequest",
+ )
+ request_time: timestamp_pb2.Timestamp = proto.Field(
+ proto.MESSAGE,
+ number=2,
+ message=timestamp_pb2.Timestamp,
+ )
+ finish_time: timestamp_pb2.Timestamp = proto.Field(
+ proto.MESSAGE,
+ number=3,
+ message=timestamp_pb2.Timestamp,
+ )
+
+
+class ListAuthorizedViewsRequest(proto.Message):
+ r"""Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.ListAuthorizedViews][google.bigtable.admin.v2.BigtableTableAdmin.ListAuthorizedViews]
+
+ Attributes:
+ parent (str):
+ Required. The unique name of the table for which
+ AuthorizedViews should be listed. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}``.
+ page_size (int):
+ Optional. Maximum number of results per page.
+
+ A page_size of zero lets the server choose the number of
+ items to return. A page_size which is strictly positive will
+ return at most that many items. A negative page_size will
+ cause an error.
+
+ Following the first request, subsequent paginated calls are
+ not required to pass a page_size. If a page_size is set in
+ subsequent calls, it must match the page_size given in the
+ first request.
+ page_token (str):
+ Optional. The value of ``next_page_token`` returned by a
+ previous call.
+ view (google.cloud.bigtable_admin_v2.types.AuthorizedView.ResponseView):
+ Optional. The resource_view to be applied to the returned
+ AuthorizedViews' fields. Default to NAME_ONLY.
+ """
+
+ parent: str = proto.Field(
+ proto.STRING,
+ number=1,
+ )
+ page_size: int = proto.Field(
+ proto.INT32,
+ number=2,
+ )
+ page_token: str = proto.Field(
+ proto.STRING,
+ number=3,
+ )
+ view: gba_table.AuthorizedView.ResponseView = proto.Field(
+ proto.ENUM,
+ number=4,
+ enum=gba_table.AuthorizedView.ResponseView,
+ )
+
+
+class ListAuthorizedViewsResponse(proto.Message):
+ r"""Response message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.ListAuthorizedViews][google.bigtable.admin.v2.BigtableTableAdmin.ListAuthorizedViews]
+
+ Attributes:
+ authorized_views (MutableSequence[google.cloud.bigtable_admin_v2.types.AuthorizedView]):
+ The AuthorizedViews present in the requested
+ table.
+ next_page_token (str):
+ Set if not all tables could be returned in a single
+ response. Pass this value to ``page_token`` in another
+ request to get the next page of results.
+ """
+
+ @property
+ def raw_page(self):
+ return self
+
+ authorized_views: MutableSequence[gba_table.AuthorizedView] = proto.RepeatedField(
+ proto.MESSAGE,
+ number=1,
+ message=gba_table.AuthorizedView,
+ )
+ next_page_token: str = proto.Field(
+ proto.STRING,
+ number=2,
+ )
+
+
+class GetAuthorizedViewRequest(proto.Message):
+ r"""Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.GetAuthorizedView][google.bigtable.admin.v2.BigtableTableAdmin.GetAuthorizedView]
+
+ Attributes:
+ name (str):
+ Required. The unique name of the requested AuthorizedView.
+ Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}/authorizedViews/{authorized_view}``.
+ view (google.cloud.bigtable_admin_v2.types.AuthorizedView.ResponseView):
+ Optional. The resource_view to be applied to the returned
+ AuthorizedView's fields. Default to BASIC.
+ """
+
+ name: str = proto.Field(
+ proto.STRING,
+ number=1,
+ )
+ view: gba_table.AuthorizedView.ResponseView = proto.Field(
+ proto.ENUM,
+ number=2,
+ enum=gba_table.AuthorizedView.ResponseView,
+ )
+
+
+class UpdateAuthorizedViewRequest(proto.Message):
+ r"""The request for
+ [UpdateAuthorizedView][google.bigtable.admin.v2.BigtableTableAdmin.UpdateAuthorizedView].
+
+ Attributes:
+ authorized_view (google.cloud.bigtable_admin_v2.types.AuthorizedView):
+ Required. The AuthorizedView to update. The ``name`` in
+ ``authorized_view`` is used to identify the AuthorizedView.
+ AuthorizedView name must in this format:
+ ``projects/{project}/instances/{instance}/tables/{table}/authorizedViews/{authorized_view}``.
+ update_mask (google.protobuf.field_mask_pb2.FieldMask):
+ Optional. The list of fields to update. A mask specifying
+ which fields in the AuthorizedView resource should be
+ updated. This mask is relative to the AuthorizedView
+ resource, not to the request message. A field will be
+ overwritten if it is in the mask. If empty, all fields set
+ in the request will be overwritten. A special value ``*``
+ means to overwrite all fields (including fields not set in
+ the request).
+ ignore_warnings (bool):
+ Optional. If true, ignore the safety checks
+ when updating the AuthorizedView.
+ """
+
+ authorized_view: gba_table.AuthorizedView = proto.Field(
+ proto.MESSAGE,
+ number=1,
+ message=gba_table.AuthorizedView,
+ )
+ update_mask: field_mask_pb2.FieldMask = proto.Field(
+ proto.MESSAGE,
+ number=2,
+ message=field_mask_pb2.FieldMask,
+ )
+ ignore_warnings: bool = proto.Field(
+ proto.BOOL,
+ number=3,
+ )
+
+
+class UpdateAuthorizedViewMetadata(proto.Message):
+ r"""Metadata for the google.longrunning.Operation returned by
+ [UpdateAuthorizedView][google.bigtable.admin.v2.BigtableTableAdmin.UpdateAuthorizedView].
+
+ Attributes:
+ original_request (google.cloud.bigtable_admin_v2.types.UpdateAuthorizedViewRequest):
+ The request that prompted the initiation of
+ this UpdateAuthorizedView operation.
+ request_time (google.protobuf.timestamp_pb2.Timestamp):
+ The time at which the original request was
+ received.
+ finish_time (google.protobuf.timestamp_pb2.Timestamp):
+ The time at which the operation failed or was
+ completed successfully.
+ """
+
+ original_request: "UpdateAuthorizedViewRequest" = proto.Field(
+ proto.MESSAGE,
+ number=1,
+ message="UpdateAuthorizedViewRequest",
+ )
+ request_time: timestamp_pb2.Timestamp = proto.Field(
+ proto.MESSAGE,
+ number=2,
+ message=timestamp_pb2.Timestamp,
+ )
+ finish_time: timestamp_pb2.Timestamp = proto.Field(
+ proto.MESSAGE,
+ number=3,
+ message=timestamp_pb2.Timestamp,
+ )
+
+
+class DeleteAuthorizedViewRequest(proto.Message):
+ r"""Request message for
+ [google.bigtable.admin.v2.BigtableTableAdmin.DeleteAuthorizedView][google.bigtable.admin.v2.BigtableTableAdmin.DeleteAuthorizedView]
+
+ Attributes:
+ name (str):
+ Required. The unique name of the AuthorizedView to be
+ deleted. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}/authorizedViews/{authorized_view}``.
+ etag (str):
+ Optional. The current etag of the
+ AuthorizedView. If an etag is provided and does
+ not match the current etag of the
+ AuthorizedView, deletion will be blocked and an
+ ABORTED error will be returned.
+ """
+
+ name: str = proto.Field(
+ proto.STRING,
+ number=1,
+ )
+ etag: str = proto.Field(
+ proto.STRING,
+ number=2,
+ )
+
+
+class CreateSchemaBundleRequest(proto.Message):
+ r"""The request for
+ [CreateSchemaBundle][google.bigtable.admin.v2.BigtableTableAdmin.CreateSchemaBundle].
+
+ Attributes:
+ parent (str):
+ Required. The parent resource where this schema bundle will
+ be created. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}``.
+ schema_bundle_id (str):
+ Required. The unique ID to use for the schema
+ bundle, which will become the final component of
+ the schema bundle's resource name.
+ schema_bundle (google.cloud.bigtable_admin_v2.types.SchemaBundle):
+ Required. The schema bundle to create.
+ """
+
+ parent: str = proto.Field(
+ proto.STRING,
+ number=1,
+ )
+ schema_bundle_id: str = proto.Field(
+ proto.STRING,
+ number=2,
+ )
+ schema_bundle: gba_table.SchemaBundle = proto.Field(
+ proto.MESSAGE,
+ number=3,
+ message=gba_table.SchemaBundle,
+ )
+
+
+class CreateSchemaBundleMetadata(proto.Message):
+ r"""The metadata for the Operation returned by
+ [CreateSchemaBundle][google.bigtable.admin.v2.BigtableTableAdmin.CreateSchemaBundle].
+
+ Attributes:
+ name (str):
+ The unique name identifying this schema bundle. Values are
+ of the form
+ ``projects/{project}/instances/{instance}/tables/{table}/schemaBundles/{schema_bundle}``
+ start_time (google.protobuf.timestamp_pb2.Timestamp):
+ The time at which this operation started.
+ end_time (google.protobuf.timestamp_pb2.Timestamp):
+ If set, the time at which this operation
+ finished or was canceled.
+ """
+
+ name: str = proto.Field(
+ proto.STRING,
+ number=1,
+ )
+ start_time: timestamp_pb2.Timestamp = proto.Field(
+ proto.MESSAGE,
+ number=2,
+ message=timestamp_pb2.Timestamp,
+ )
+ end_time: timestamp_pb2.Timestamp = proto.Field(
+ proto.MESSAGE,
+ number=3,
+ message=timestamp_pb2.Timestamp,
+ )
+
+
+class UpdateSchemaBundleRequest(proto.Message):
+ r"""The request for
+ [UpdateSchemaBundle][google.bigtable.admin.v2.BigtableTableAdmin.UpdateSchemaBundle].
+
+ Attributes:
+ schema_bundle (google.cloud.bigtable_admin_v2.types.SchemaBundle):
+ Required. The schema bundle to update.
+
+ The schema bundle's ``name`` field is used to identify the
+ schema bundle to update. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}/schemaBundles/{schema_bundle}``
+ update_mask (google.protobuf.field_mask_pb2.FieldMask):
+ Optional. The list of fields to update.
+ ignore_warnings (bool):
+ Optional. If set, ignore the safety checks
+ when updating the Schema Bundle. The safety
+ checks are:
+
+ - The new Schema Bundle is backwards compatible
+ with the existing Schema Bundle.
+ """
+
+ schema_bundle: gba_table.SchemaBundle = proto.Field(
+ proto.MESSAGE,
+ number=1,
+ message=gba_table.SchemaBundle,
+ )
+ update_mask: field_mask_pb2.FieldMask = proto.Field(
+ proto.MESSAGE,
+ number=2,
+ message=field_mask_pb2.FieldMask,
+ )
+ ignore_warnings: bool = proto.Field(
+ proto.BOOL,
+ number=3,
+ )
+
+
+class UpdateSchemaBundleMetadata(proto.Message):
+ r"""The metadata for the Operation returned by
+ [UpdateSchemaBundle][google.bigtable.admin.v2.BigtableTableAdmin.UpdateSchemaBundle].
+
+ Attributes:
+ name (str):
+ The unique name identifying this schema bundle. Values are
+ of the form
+ ``projects/{project}/instances/{instance}/tables/{table}/schemaBundles/{schema_bundle}``
+ start_time (google.protobuf.timestamp_pb2.Timestamp):
+ The time at which this operation started.
+ end_time (google.protobuf.timestamp_pb2.Timestamp):
+ If set, the time at which this operation
+ finished or was canceled.
+ """
+
+ name: str = proto.Field(
+ proto.STRING,
+ number=1,
+ )
+ start_time: timestamp_pb2.Timestamp = proto.Field(
+ proto.MESSAGE,
+ number=2,
+ message=timestamp_pb2.Timestamp,
+ )
+ end_time: timestamp_pb2.Timestamp = proto.Field(
+ proto.MESSAGE,
+ number=3,
+ message=timestamp_pb2.Timestamp,
+ )
+
+
+class GetSchemaBundleRequest(proto.Message):
+ r"""The request for
+ [GetSchemaBundle][google.bigtable.admin.v2.BigtableTableAdmin.GetSchemaBundle].
+
+ Attributes:
+ name (str):
+ Required. The unique name of the schema bundle to retrieve.
+ Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}/schemaBundles/{schema_bundle}``
+ """
+
+ name: str = proto.Field(
+ proto.STRING,
+ number=1,
+ )
+
+
+class ListSchemaBundlesRequest(proto.Message):
+ r"""The request for
+ [ListSchemaBundles][google.bigtable.admin.v2.BigtableTableAdmin.ListSchemaBundles].
+
+ Attributes:
+ parent (str):
+ Required. The parent, which owns this collection of schema
+ bundles. Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}``.
+ page_size (int):
+ The maximum number of schema bundles to
+ return. If the value is positive, the server may
+ return at most this value. If unspecified, the
+ server will return the maximum allowed page
+ size.
+ page_token (str):
+ A page token, received from a previous ``ListSchemaBundles``
+ call. Provide this to retrieve the subsequent page.
+
+ When paginating, all other parameters provided to
+ ``ListSchemaBundles`` must match the call that provided the
+ page token.
+ """
+
+ parent: str = proto.Field(
+ proto.STRING,
+ number=1,
+ )
+ page_size: int = proto.Field(
+ proto.INT32,
+ number=2,
+ )
+ page_token: str = proto.Field(
+ proto.STRING,
+ number=3,
+ )
+
+
+class ListSchemaBundlesResponse(proto.Message):
+ r"""The response for
+ [ListSchemaBundles][google.bigtable.admin.v2.BigtableTableAdmin.ListSchemaBundles].
+
+ Attributes:
+ schema_bundles (MutableSequence[google.cloud.bigtable_admin_v2.types.SchemaBundle]):
+ The schema bundles from the specified table.
+ next_page_token (str):
+ A token, which can be sent as ``page_token`` to retrieve the
+ next page. If this field is omitted, there are no subsequent
+ pages.
+ """
+
+ @property
+ def raw_page(self):
+ return self
+
+ schema_bundles: MutableSequence[gba_table.SchemaBundle] = proto.RepeatedField(
+ proto.MESSAGE,
+ number=1,
+ message=gba_table.SchemaBundle,
+ )
+ next_page_token: str = proto.Field(
+ proto.STRING,
+ number=2,
+ )
+
+
+class DeleteSchemaBundleRequest(proto.Message):
+ r"""The request for
+ [DeleteSchemaBundle][google.bigtable.admin.v2.BigtableTableAdmin.DeleteSchemaBundle].
+
+ Attributes:
+ name (str):
+ Required. The unique name of the schema bundle to delete.
+ Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}/schemaBundles/{schema_bundle}``
+ etag (str):
+ Optional. The etag of the schema bundle.
+ If this is provided, it must match the server's
+ etag. The server returns an ABORTED error on a
+ mismatched etag.
+ """
+
+ name: str = proto.Field(
+ proto.STRING,
+ number=1,
+ )
+ etag: str = proto.Field(
proto.STRING,
number=2,
)
diff --git a/google/cloud/bigtable_admin_v2/types/common.py b/google/cloud/bigtable_admin_v2/types/common.py
index 704a07732..7b05e5ff5 100644
--- a/google/cloud/bigtable_admin_v2/types/common.py
+++ b/google/cloud/bigtable_admin_v2/types/common.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -13,6 +13,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+from __future__ import annotations
+
+from typing import MutableMapping, MutableSequence
+
import proto # type: ignore
from google.protobuf import timestamp_pb2 # type: ignore
@@ -28,7 +32,16 @@
class StorageType(proto.Enum):
- r"""Storage media types for persisting Bigtable data."""
+ r"""Storage media types for persisting Bigtable data.
+
+ Values:
+ STORAGE_TYPE_UNSPECIFIED (0):
+ The user did not specify a storage type.
+ SSD (1):
+ Flash (SSD) storage should be used.
+ HDD (2):
+ Magnetic drive (HDD) storage should be used.
+ """
STORAGE_TYPE_UNSPECIFIED = 0
SSD = 1
HDD = 2
@@ -49,16 +62,16 @@ class OperationProgress(proto.Message):
failed or was completed successfully.
"""
- progress_percent = proto.Field(
+ progress_percent: int = proto.Field(
proto.INT32,
number=1,
)
- start_time = proto.Field(
+ start_time: timestamp_pb2.Timestamp = proto.Field(
proto.MESSAGE,
number=2,
message=timestamp_pb2.Timestamp,
)
- end_time = proto.Field(
+ end_time: timestamp_pb2.Timestamp = proto.Field(
proto.MESSAGE,
number=3,
message=timestamp_pb2.Timestamp,
diff --git a/google/cloud/bigtable_admin_v2/types/instance.py b/google/cloud/bigtable_admin_v2/types/instance.py
index 1b2e4d615..f07414d56 100644
--- a/google/cloud/bigtable_admin_v2/types/instance.py
+++ b/google/cloud/bigtable_admin_v2/types/instance.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -13,6 +13,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+from __future__ import annotations
+
+from typing import MutableMapping, MutableSequence
+
import proto # type: ignore
from google.cloud.bigtable_admin_v2.types import common
@@ -28,6 +32,8 @@
"Cluster",
"AppProfile",
"HotTablet",
+ "LogicalView",
+ "MaterializedView",
},
)
@@ -38,6 +44,9 @@ class Instance(proto.Message):
served from all [Clusters][google.bigtable.admin.v2.Cluster] in the
instance.
+
+ .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields
+
Attributes:
name (str):
The unique name of the instance. Values are of the form
@@ -48,71 +57,137 @@ class Instance(proto.Message):
any time, but should be kept globally unique to
avoid confusion.
state (google.cloud.bigtable_admin_v2.types.Instance.State):
- (``OutputOnly``) The current state of the instance.
+ Output only. The current state of the
+ instance.
type_ (google.cloud.bigtable_admin_v2.types.Instance.Type):
The type of the instance. Defaults to ``PRODUCTION``.
- labels (Mapping[str, str]):
+ labels (MutableMapping[str, str]):
Labels are a flexible and lightweight mechanism for
organizing cloud resources into groups that reflect a
customer's organizational needs and deployment strategies.
They can be used to filter resources and aggregate metrics.
- - Label keys must be between 1 and 63 characters long and
- must conform to the regular expression:
- ``[\p{Ll}\p{Lo}][\p{Ll}\p{Lo}\p{N}_-]{0,62}``.
- - Label values must be between 0 and 63 characters long and
- must conform to the regular expression:
- ``[\p{Ll}\p{Lo}\p{N}_-]{0,63}``.
- - No more than 64 labels can be associated with a given
- resource.
- - Keys and values must both be under 128 bytes.
+ - Label keys must be between 1 and 63 characters long and
+ must conform to the regular expression:
+ ``[\p{Ll}\p{Lo}][\p{Ll}\p{Lo}\p{N}_-]{0,62}``.
+ - Label values must be between 0 and 63 characters long and
+ must conform to the regular expression:
+ ``[\p{Ll}\p{Lo}\p{N}_-]{0,63}``.
+ - No more than 64 labels can be associated with a given
+ resource.
+ - Keys and values must both be under 128 bytes.
create_time (google.protobuf.timestamp_pb2.Timestamp):
- Output only. A server-assigned timestamp representing when
- this Instance was created. For instances created before this
+ Output only. A commit timestamp representing when this
+ Instance was created. For instances created before this
field was added (August 2021), this value is
``seconds: 0, nanos: 1``.
+ satisfies_pzs (bool):
+ Output only. Reserved for future use.
+
+ This field is a member of `oneof`_ ``_satisfies_pzs``.
+ satisfies_pzi (bool):
+ Output only. Reserved for future use.
+
+ This field is a member of `oneof`_ ``_satisfies_pzi``.
+ tags (MutableMapping[str, str]):
+ Optional. Input only. Immutable. Tag
+ keys/values directly bound to this resource. For
+ example:
+
+ - "123/environment": "production",
+ - "123/costCenter": "marketing"
+
+ Tags and Labels (above) are both used to bind
+ metadata to resources, with different use-cases.
+ See
+ https://cloud.google.com/resource-manager/docs/tags/tags-overview
+ for an in-depth overview on the difference
+ between tags and labels.
"""
class State(proto.Enum):
- r"""Possible states of an instance."""
+ r"""Possible states of an instance.
+
+ Values:
+ STATE_NOT_KNOWN (0):
+ The state of the instance could not be
+ determined.
+ READY (1):
+ The instance has been successfully created
+ and can serve requests to its tables.
+ CREATING (2):
+ The instance is currently being created, and
+ may be destroyed if the creation process
+ encounters an error.
+ """
STATE_NOT_KNOWN = 0
READY = 1
CREATING = 2
class Type(proto.Enum):
- r"""The type of the instance."""
+ r"""The type of the instance.
+
+ Values:
+ TYPE_UNSPECIFIED (0):
+ The type of the instance is unspecified. If set when
+ creating an instance, a ``PRODUCTION`` instance will be
+ created. If set when updating an instance, the type will be
+ left unchanged.
+ PRODUCTION (1):
+ An instance meant for production use. ``serve_nodes`` must
+ be set on the cluster.
+ DEVELOPMENT (2):
+ DEPRECATED: Prefer PRODUCTION for all use
+ cases, as it no longer enforces a higher minimum
+ node count than DEVELOPMENT.
+ """
TYPE_UNSPECIFIED = 0
PRODUCTION = 1
DEVELOPMENT = 2
- name = proto.Field(
+ name: str = proto.Field(
proto.STRING,
number=1,
)
- display_name = proto.Field(
+ display_name: str = proto.Field(
proto.STRING,
number=2,
)
- state = proto.Field(
+ state: State = proto.Field(
proto.ENUM,
number=3,
enum=State,
)
- type_ = proto.Field(
+ type_: Type = proto.Field(
proto.ENUM,
number=4,
enum=Type,
)
- labels = proto.MapField(
+ labels: MutableMapping[str, str] = proto.MapField(
proto.STRING,
proto.STRING,
number=5,
)
- create_time = proto.Field(
+ create_time: timestamp_pb2.Timestamp = proto.Field(
proto.MESSAGE,
number=7,
message=timestamp_pb2.Timestamp,
)
+ satisfies_pzs: bool = proto.Field(
+ proto.BOOL,
+ number=8,
+ optional=True,
+ )
+ satisfies_pzi: bool = proto.Field(
+ proto.BOOL,
+ number=11,
+ optional=True,
+ )
+ tags: MutableMapping[str, str] = proto.MapField(
+ proto.STRING,
+ proto.STRING,
+ number=12,
+ )
class AutoscalingTargets(proto.Message):
@@ -125,12 +200,24 @@ class AutoscalingTargets(proto.Message):
achieve. This number is on a scale from 0 (no utilization)
to 100 (total utilization), and is limited between 10 and
80, otherwise it will return INVALID_ARGUMENT error.
+ storage_utilization_gib_per_node (int):
+ The storage utilization that the Autoscaler should be trying
+ to achieve. This number is limited between 2560 (2.5TiB) and
+ 5120 (5TiB) for a SSD cluster and between 8192 (8TiB) and
+ 16384 (16TiB) for an HDD cluster, otherwise it will return
+ INVALID_ARGUMENT error. If this value is set to 0, it will
+ be treated as if it were set to the default value: 2560 for
+ SSD, 8192 for HDD.
"""
- cpu_utilization_percent = proto.Field(
+ cpu_utilization_percent: int = proto.Field(
proto.INT32,
number=2,
)
+ storage_utilization_gib_per_node: int = proto.Field(
+ proto.INT32,
+ number=3,
+ )
class AutoscalingLimits(proto.Message):
@@ -146,11 +233,11 @@ class AutoscalingLimits(proto.Message):
to.
"""
- min_serve_nodes = proto.Field(
+ min_serve_nodes: int = proto.Field(
proto.INT32,
number=1,
)
- max_serve_nodes = proto.Field(
+ max_serve_nodes: int = proto.Field(
proto.INT32,
number=2,
)
@@ -178,9 +265,13 @@ class Cluster(proto.Message):
Output only. The current state of the
cluster.
serve_nodes (int):
- The number of nodes allocated to this
- cluster. More nodes enable higher throughput and
- more consistent performance.
+ The number of nodes in the cluster. If no
+ value is set, Cloud Bigtable automatically
+ allocates nodes based on your data footprint and
+ optimized for 50% storage utilization.
+ node_scaling_factor (google.cloud.bigtable_admin_v2.types.Cluster.NodeScalingFactor):
+ Immutable. The node scaling factor of this
+ cluster.
cluster_config (google.cloud.bigtable_admin_v2.types.Cluster.ClusterConfig):
Configuration for this cluster.
@@ -195,13 +286,61 @@ class Cluster(proto.Message):
"""
class State(proto.Enum):
- r"""Possible states of a cluster."""
+ r"""Possible states of a cluster.
+
+ Values:
+ STATE_NOT_KNOWN (0):
+ The state of the cluster could not be
+ determined.
+ READY (1):
+ The cluster has been successfully created and
+ is ready to serve requests.
+ CREATING (2):
+ The cluster is currently being created, and
+ may be destroyed if the creation process
+ encounters an error. A cluster may not be able
+ to serve requests while being created.
+ RESIZING (3):
+ The cluster is currently being resized, and
+ may revert to its previous node count if the
+ process encounters an error. A cluster is still
+ capable of serving requests while being resized,
+ but may exhibit performance as if its number of
+ allocated nodes is between the starting and
+ requested states.
+ DISABLED (4):
+ The cluster has no backing nodes. The data
+ (tables) still exist, but no operations can be
+ performed on the cluster.
+ """
STATE_NOT_KNOWN = 0
READY = 1
CREATING = 2
RESIZING = 3
DISABLED = 4
+ class NodeScalingFactor(proto.Enum):
+ r"""Possible node scaling factors of the clusters. Node scaling
+ delivers better latency and more throughput by removing node
+ boundaries.
+
+ Values:
+ NODE_SCALING_FACTOR_UNSPECIFIED (0):
+ No node scaling specified. Defaults to
+ NODE_SCALING_FACTOR_1X.
+ NODE_SCALING_FACTOR_1X (1):
+ The cluster is running with a scaling factor
+ of 1.
+ NODE_SCALING_FACTOR_2X (2):
+ The cluster is running with a scaling factor of 2. All node
+ count values must be in increments of 2 with this scaling
+ factor enabled, otherwise an INVALID_ARGUMENT error will be
+ returned.
+ """
+ NODE_SCALING_FACTOR_UNSPECIFIED = 0
+ NODE_SCALING_FACTOR_1X = 1
+ NODE_SCALING_FACTOR_2X = 2
+
class ClusterAutoscalingConfig(proto.Message):
r"""Autoscaling config for a cluster.
@@ -214,12 +353,12 @@ class ClusterAutoscalingConfig(proto.Message):
cluster.
"""
- autoscaling_limits = proto.Field(
+ autoscaling_limits: "AutoscalingLimits" = proto.Field(
proto.MESSAGE,
number=1,
message="AutoscalingLimits",
)
- autoscaling_targets = proto.Field(
+ autoscaling_targets: "AutoscalingTargets" = proto.Field(
proto.MESSAGE,
number=2,
message="AutoscalingTargets",
@@ -233,7 +372,7 @@ class ClusterConfig(proto.Message):
Autoscaling configuration for this cluster.
"""
- cluster_autoscaling_config = proto.Field(
+ cluster_autoscaling_config: "Cluster.ClusterAutoscalingConfig" = proto.Field(
proto.MESSAGE,
number=1,
message="Cluster.ClusterAutoscalingConfig",
@@ -254,46 +393,50 @@ class EncryptionConfig(proto.Message):
``cloudkms.cryptoKeyEncrypterDecrypter`` role on the CMEK
key.
2) Only regional keys can be used and the region of the CMEK
- key must match the region of the cluster.
- 3) All clusters within an instance must use the same CMEK
- key. Values are of the form
+ key must match the region of the cluster. Values are of
+ the form
``projects/{project}/locations/{location}/keyRings/{keyring}/cryptoKeys/{key}``
"""
- kms_key_name = proto.Field(
+ kms_key_name: str = proto.Field(
proto.STRING,
number=1,
)
- name = proto.Field(
+ name: str = proto.Field(
proto.STRING,
number=1,
)
- location = proto.Field(
+ location: str = proto.Field(
proto.STRING,
number=2,
)
- state = proto.Field(
+ state: State = proto.Field(
proto.ENUM,
number=3,
enum=State,
)
- serve_nodes = proto.Field(
+ serve_nodes: int = proto.Field(
proto.INT32,
number=4,
)
- cluster_config = proto.Field(
+ node_scaling_factor: NodeScalingFactor = proto.Field(
+ proto.ENUM,
+ number=9,
+ enum=NodeScalingFactor,
+ )
+ cluster_config: ClusterConfig = proto.Field(
proto.MESSAGE,
number=7,
oneof="config",
message=ClusterConfig,
)
- default_storage_type = proto.Field(
+ default_storage_type: common.StorageType = proto.Field(
proto.ENUM,
number=5,
enum=common.StorageType,
)
- encryption_config = proto.Field(
+ encryption_config: EncryptionConfig = proto.Field(
proto.MESSAGE,
number=6,
message=EncryptionConfig,
@@ -337,8 +480,48 @@ class AppProfile(proto.Message):
Use a single-cluster routing policy.
This field is a member of `oneof`_ ``routing_policy``.
+ priority (google.cloud.bigtable_admin_v2.types.AppProfile.Priority):
+ This field has been deprecated in favor of
+ ``standard_isolation.priority``. If you set this field,
+ ``standard_isolation.priority`` will be set instead.
+
+ The priority of requests sent using this app profile.
+
+ This field is a member of `oneof`_ ``isolation``.
+ standard_isolation (google.cloud.bigtable_admin_v2.types.AppProfile.StandardIsolation):
+ The standard options used for isolating this
+ app profile's traffic from other use cases.
+
+ This field is a member of `oneof`_ ``isolation``.
+ data_boost_isolation_read_only (google.cloud.bigtable_admin_v2.types.AppProfile.DataBoostIsolationReadOnly):
+ Specifies that this app profile is intended
+ for read-only usage via the Data Boost feature.
+
+ This field is a member of `oneof`_ ``isolation``.
"""
+ class Priority(proto.Enum):
+ r"""Possible priorities for an app profile. Note that higher
+ priority writes can sometimes queue behind lower priority writes
+ to the same tablet, as writes must be strictly sequenced in the
+ durability log.
+
+ Values:
+ PRIORITY_UNSPECIFIED (0):
+ Default value. Mapped to PRIORITY_HIGH (the legacy behavior)
+ on creation.
+ PRIORITY_LOW (1):
+ No description available.
+ PRIORITY_MEDIUM (2):
+ No description available.
+ PRIORITY_HIGH (3):
+ No description available.
+ """
+ PRIORITY_UNSPECIFIED = 0
+ PRIORITY_LOW = 1
+ PRIORITY_MEDIUM = 2
+ PRIORITY_HIGH = 3
+
class MultiClusterRoutingUseAny(proto.Message):
r"""Read/write requests are routed to the nearest cluster in the
instance, and will fail over to the nearest cluster that is
@@ -346,18 +529,47 @@ class MultiClusterRoutingUseAny(proto.Message):
in a region are considered equidistant. Choosing this option
sacrifices read-your-writes consistency to improve availability.
+
+ .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields
+
Attributes:
- cluster_ids (Sequence[str]):
+ cluster_ids (MutableSequence[str]):
The set of clusters to route to. The order is
ignored; clusters will be tried in order of
distance. If left empty, all clusters are
eligible.
+ row_affinity (google.cloud.bigtable_admin_v2.types.AppProfile.MultiClusterRoutingUseAny.RowAffinity):
+ Row affinity sticky routing based on the row
+ key of the request. Requests that span multiple
+ rows are routed non-deterministically.
+
+ This field is a member of `oneof`_ ``affinity``.
"""
- cluster_ids = proto.RepeatedField(
+ class RowAffinity(proto.Message):
+ r"""If enabled, Bigtable will route the request based on the row
+ key of the request, rather than randomly. Instead, each row key
+ will be assigned to a cluster, and will stick to that cluster.
+ If clusters are added or removed, then this may affect which row
+ keys stick to which clusters. To avoid this, users can use a
+ cluster group to specify which clusters are to be used. In this
+ case, new clusters that are not a part of the cluster group will
+ not be routed to, and routing will be unaffected by the new
+ cluster. Moreover, clusters specified in the cluster group
+ cannot be deleted unless removed from the cluster group.
+
+ """
+
+ cluster_ids: MutableSequence[str] = proto.RepeatedField(
proto.STRING,
number=1,
)
+ row_affinity: "AppProfile.MultiClusterRoutingUseAny.RowAffinity" = proto.Field(
+ proto.MESSAGE,
+ number=3,
+ oneof="affinity",
+ message="AppProfile.MultiClusterRoutingUseAny.RowAffinity",
+ )
class SingleClusterRouting(proto.Message):
r"""Unconditionally routes all read/write requests to a specific
@@ -375,39 +587,114 @@ class SingleClusterRouting(proto.Message):
table/row/column in multiple clusters.
"""
- cluster_id = proto.Field(
+ cluster_id: str = proto.Field(
proto.STRING,
number=1,
)
- allow_transactional_writes = proto.Field(
+ allow_transactional_writes: bool = proto.Field(
proto.BOOL,
number=2,
)
- name = proto.Field(
+ class StandardIsolation(proto.Message):
+ r"""Standard options for isolating this app profile's traffic
+ from other use cases.
+
+ Attributes:
+ priority (google.cloud.bigtable_admin_v2.types.AppProfile.Priority):
+ The priority of requests sent using this app
+ profile.
+ """
+
+ priority: "AppProfile.Priority" = proto.Field(
+ proto.ENUM,
+ number=1,
+ enum="AppProfile.Priority",
+ )
+
+ class DataBoostIsolationReadOnly(proto.Message):
+ r"""Data Boost is a serverless compute capability that lets you
+ run high-throughput read jobs and queries on your Bigtable data,
+ without impacting the performance of the clusters that handle
+ your application traffic. Data Boost supports read-only use
+ cases with single-cluster routing.
+
+
+ .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields
+
+ Attributes:
+ compute_billing_owner (google.cloud.bigtable_admin_v2.types.AppProfile.DataBoostIsolationReadOnly.ComputeBillingOwner):
+ The Compute Billing Owner for this Data Boost
+ App Profile.
+
+ This field is a member of `oneof`_ ``_compute_billing_owner``.
+ """
+
+ class ComputeBillingOwner(proto.Enum):
+ r"""Compute Billing Owner specifies how usage should be accounted
+ when using Data Boost. Compute Billing Owner also configures
+ which Cloud Project is charged for relevant quota.
+
+ Values:
+ COMPUTE_BILLING_OWNER_UNSPECIFIED (0):
+ Unspecified value.
+ HOST_PAYS (1):
+ The host Cloud Project containing the
+ targeted Bigtable Instance / Table pays for
+ compute.
+ """
+ COMPUTE_BILLING_OWNER_UNSPECIFIED = 0
+ HOST_PAYS = 1
+
+ compute_billing_owner: "AppProfile.DataBoostIsolationReadOnly.ComputeBillingOwner" = proto.Field(
+ proto.ENUM,
+ number=1,
+ optional=True,
+ enum="AppProfile.DataBoostIsolationReadOnly.ComputeBillingOwner",
+ )
+
+ name: str = proto.Field(
proto.STRING,
number=1,
)
- etag = proto.Field(
+ etag: str = proto.Field(
proto.STRING,
number=2,
)
- description = proto.Field(
+ description: str = proto.Field(
proto.STRING,
number=3,
)
- multi_cluster_routing_use_any = proto.Field(
+ multi_cluster_routing_use_any: MultiClusterRoutingUseAny = proto.Field(
proto.MESSAGE,
number=5,
oneof="routing_policy",
message=MultiClusterRoutingUseAny,
)
- single_cluster_routing = proto.Field(
+ single_cluster_routing: SingleClusterRouting = proto.Field(
proto.MESSAGE,
number=6,
oneof="routing_policy",
message=SingleClusterRouting,
)
+ priority: Priority = proto.Field(
+ proto.ENUM,
+ number=7,
+ oneof="isolation",
+ enum=Priority,
+ )
+ standard_isolation: StandardIsolation = proto.Field(
+ proto.MESSAGE,
+ number=11,
+ oneof="isolation",
+ message=StandardIsolation,
+ )
+ data_boost_isolation_read_only: DataBoostIsolationReadOnly = proto.Field(
+ proto.MESSAGE,
+ number=10,
+ oneof="isolation",
+ message=DataBoostIsolationReadOnly,
+ )
class HotTablet(proto.Message):
@@ -443,36 +730,116 @@ class HotTablet(proto.Message):
(the node spent all cycles serving the hot tablet).
"""
- name = proto.Field(
+ name: str = proto.Field(
proto.STRING,
number=1,
)
- table_name = proto.Field(
+ table_name: str = proto.Field(
proto.STRING,
number=2,
)
- start_time = proto.Field(
+ start_time: timestamp_pb2.Timestamp = proto.Field(
proto.MESSAGE,
number=3,
message=timestamp_pb2.Timestamp,
)
- end_time = proto.Field(
+ end_time: timestamp_pb2.Timestamp = proto.Field(
proto.MESSAGE,
number=4,
message=timestamp_pb2.Timestamp,
)
- start_key = proto.Field(
+ start_key: str = proto.Field(
proto.STRING,
number=5,
)
- end_key = proto.Field(
+ end_key: str = proto.Field(
proto.STRING,
number=6,
)
- node_cpu_usage_percent = proto.Field(
+ node_cpu_usage_percent: float = proto.Field(
proto.FLOAT,
number=7,
)
+class LogicalView(proto.Message):
+ r"""A SQL logical view object that can be referenced in SQL
+ queries.
+
+ Attributes:
+ name (str):
+ Identifier. The unique name of the logical view. Format:
+ ``projects/{project}/instances/{instance}/logicalViews/{logical_view}``
+ query (str):
+ Required. The logical view's select query.
+ etag (str):
+ Optional. The etag for this logical view.
+ This may be sent on update requests to ensure
+ that the client has an up-to-date value before
+ proceeding. The server returns an ABORTED error
+ on a mismatched etag.
+ deletion_protection (bool):
+ Optional. Set to true to make the LogicalView
+ protected against deletion.
+ """
+
+ name: str = proto.Field(
+ proto.STRING,
+ number=1,
+ )
+ query: str = proto.Field(
+ proto.STRING,
+ number=2,
+ )
+ etag: str = proto.Field(
+ proto.STRING,
+ number=3,
+ )
+ deletion_protection: bool = proto.Field(
+ proto.BOOL,
+ number=6,
+ )
+
+
+class MaterializedView(proto.Message):
+ r"""A materialized view object that can be referenced in SQL
+ queries.
+
+ Attributes:
+ name (str):
+ Identifier. The unique name of the materialized view.
+ Format:
+ ``projects/{project}/instances/{instance}/materializedViews/{materialized_view}``
+ query (str):
+ Required. Immutable. The materialized view's
+ select query.
+ etag (str):
+ Optional. The etag for this materialized
+ view. This may be sent on update requests to
+ ensure that the client has an up-to-date value
+ before proceeding. The server returns an ABORTED
+ error on a mismatched etag.
+ deletion_protection (bool):
+ Set to true to make the MaterializedView
+ protected against deletion.
+ """
+
+ name: str = proto.Field(
+ proto.STRING,
+ number=1,
+ )
+ query: str = proto.Field(
+ proto.STRING,
+ number=2,
+ )
+ etag: str = proto.Field(
+ proto.STRING,
+ number=3,
+ )
+ deletion_protection: bool = proto.Field(
+ proto.BOOL,
+ number=6,
+ )
+
+
__all__ = tuple(sorted(__protobuf__.manifest))
diff --git a/google/cloud/bigtable_admin_v2/types/table.py b/google/cloud/bigtable_admin_v2/types/table.py
index 183b88086..c4f23d5fa 100644
--- a/google/cloud/bigtable_admin_v2/types/table.py
+++ b/google/cloud/bigtable_admin_v2/types/table.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -13,8 +13,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+from __future__ import annotations
+
+from typing import MutableMapping, MutableSequence
+
import proto # type: ignore
+from google.cloud.bigtable_admin_v2.types import types
+from google.cloud.bigtable_admin_v2.utils import oneof_message
from google.protobuf import duration_pb2 # type: ignore
from google.protobuf import timestamp_pb2 # type: ignore
from google.rpc import status_pb2 # type: ignore
@@ -25,19 +31,33 @@
manifest={
"RestoreSourceType",
"RestoreInfo",
+ "ChangeStreamConfig",
"Table",
+ "AuthorizedView",
"ColumnFamily",
"GcRule",
"EncryptionInfo",
"Snapshot",
"Backup",
"BackupInfo",
+ "TieredStorageConfig",
+ "TieredStorageRule",
+ "ProtoSchema",
+ "SchemaBundle",
},
)
class RestoreSourceType(proto.Enum):
- r"""Indicates the type of the restore source."""
+ r"""Indicates the type of the restore source.
+
+ Values:
+ RESTORE_SOURCE_TYPE_UNSPECIFIED (0):
+ No restore associated.
+ BACKUP (1):
+ A backup was used as the source of the
+ restore.
+ """
RESTORE_SOURCE_TYPE_UNSPECIFIED = 0
BACKUP = 1
@@ -57,12 +77,12 @@ class RestoreInfo(proto.Message):
This field is a member of `oneof`_ ``source_info``.
"""
- source_type = proto.Field(
+ source_type: "RestoreSourceType" = proto.Field(
proto.ENUM,
number=1,
enum="RestoreSourceType",
)
- backup_info = proto.Field(
+ backup_info: "BackupInfo" = proto.Field(
proto.MESSAGE,
number=2,
oneof="source_info",
@@ -70,27 +90,52 @@ class RestoreInfo(proto.Message):
)
+class ChangeStreamConfig(proto.Message):
+ r"""Change stream configuration.
+
+ Attributes:
+ retention_period (google.protobuf.duration_pb2.Duration):
+ How long the change stream should be
+ retained. Change stream data older than the
+ retention period will not be returned when
+ reading the change stream from the table.
+ Values must be at least 1 day and at most 7
+ days, and will be truncated to microsecond
+ granularity.
+ """
+
+ retention_period: duration_pb2.Duration = proto.Field(
+ proto.MESSAGE,
+ number=1,
+ message=duration_pb2.Duration,
+ )
+
+
class Table(proto.Message):
r"""A collection of user data indexed by row, column, and
timestamp. Each table is served using the resources of its
parent cluster.
+
+ .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields
+
Attributes:
name (str):
The unique name of the table. Values are of the form
``projects/{project}/instances/{instance}/tables/[_a-zA-Z0-9][-_.a-zA-Z0-9]*``.
Views: ``NAME_ONLY``, ``SCHEMA_VIEW``, ``REPLICATION_VIEW``,
``FULL``
- cluster_states (Mapping[str, google.cloud.bigtable_admin_v2.types.Table.ClusterState]):
+ cluster_states (MutableMapping[str, google.cloud.bigtable_admin_v2.types.Table.ClusterState]):
Output only. Map from cluster ID to per-cluster table state.
If it could not be determined whether or not the table has
data in a particular cluster (for example, if its zone is
unavailable), then there will be an entry for the cluster
with UNKNOWN ``replication_status``. Views:
``REPLICATION_VIEW``, ``ENCRYPTION_VIEW``, ``FULL``
- column_families (Mapping[str, google.cloud.bigtable_admin_v2.types.ColumnFamily]):
+ column_families (MutableMapping[str, google.cloud.bigtable_admin_v2.types.ColumnFamily]):
The column families configured for this table, mapped by
- column family ID. Views: ``SCHEMA_VIEW``, ``FULL``
+ column family ID. Views: ``SCHEMA_VIEW``, ``STATS_VIEW``,
+ ``FULL``
granularity (google.cloud.bigtable_admin_v2.types.Table.TimestampGranularity):
Immutable. The granularity (i.e. ``MILLIS``) at which
timestamps are stored in this table. Timestamps not matching
@@ -102,17 +147,130 @@ class Table(proto.Message):
another data source (e.g. a backup), this field
will be populated with information about the
restore.
+ change_stream_config (google.cloud.bigtable_admin_v2.types.ChangeStreamConfig):
+ If specified, enable the change stream on
+ this table. Otherwise, the change stream is
+ disabled and the change stream is not retained.
+ deletion_protection (bool):
+ Set to true to make the table protected against data loss.
+ i.e. deleting the following resources through Admin APIs are
+ prohibited:
+
+ - The table.
+ - The column families in the table.
+ - The instance containing the table.
+
+ Note one can still delete the data stored in the table
+ through Data APIs.
+ automated_backup_policy (google.cloud.bigtable_admin_v2.types.Table.AutomatedBackupPolicy):
+ If specified, automated backups are enabled
+ for this table. Otherwise, automated backups are
+ disabled.
+
+ This field is a member of `oneof`_ ``automated_backup_config``.
+ tiered_storage_config (google.cloud.bigtable_admin_v2.types.TieredStorageConfig):
+ Rules to specify what data is stored in each
+ storage tier. Different tiers store data
+ differently, providing different trade-offs
+ between cost and performance. Different parts of
+ a table can be stored separately on different
+ tiers.
+ If a config is specified, tiered storage is
+ enabled for this table. Otherwise, tiered
+ storage is disabled.
+ Only SSD instances can configure tiered storage.
+ row_key_schema (google.cloud.bigtable_admin_v2.types.Type.Struct):
+ The row key schema for this table. The schema is used to
+ decode the raw row key bytes into a structured format. The
+ order of field declarations in this schema is important, as
+ it reflects how the raw row key bytes are structured.
+ Currently, this only affects how the key is read via a
+ GoogleSQL query from the ExecuteQuery API.
+
+ For a SQL query, the \_key column is still read as raw
+ bytes. But queries can reference the key fields by name,
+ which will be decoded from \_key using provided type and
+ encoding. Queries that reference key fields will fail if
+ they encounter an invalid row key.
+
+ For example, if \_key =
+ "some_id#2024-04-30#\\x00\\x13\\x00\\xf3" with the following
+ schema: { fields { field_name: "id" type { string {
+ encoding: utf8_bytes {} } } } fields { field_name: "date"
+ type { string { encoding: utf8_bytes {} } } } fields {
+ field_name: "product_code" type { int64 { encoding:
+ big_endian_bytes {} } } } encoding { delimited_bytes {
+ delimiter: "#" } } }
+
+ | The decoded key parts would be: id = "some_id", date =
+ "2024-04-30", product_code = 1245427 The query "SELECT
+ \_key, product_code FROM table" will return two columns:
+ /------------------------------------------------------
+ | \| \_key \| product_code \| \|
+ --------------------------------------\|--------------\|
+ \| "some_id#2024-04-30#\\x00\\x13\\x00\\xf3" \| 1245427 \|
+ ------------------------------------------------------/
+
+ The schema has the following invariants: (1) The decoded
+ field values are order-preserved. For read, the field values
+ will be decoded in sorted mode from the raw bytes. (2) Every
+ field in the schema must specify a non-empty name. (3) Every
+ field must specify a type with an associated encoding. The
+ type is limited to scalar types only: Array, Map, Aggregate,
+ and Struct are not allowed. (4) The field names must not
+ collide with existing column family names and reserved
+ keywords "\_key" and "\_timestamp".
+
+ The following update operations are allowed for
+ row_key_schema:
+
+ - Update from an empty schema to a new schema.
+ - Remove the existing schema. This operation requires
+ setting the ``ignore_warnings`` flag to ``true``, since it
+ might be a backward incompatible change. Without the flag,
+ the update request will fail with an INVALID_ARGUMENT
+ error. Any other row key schema update operation (e.g.
+ update existing schema columns names or types) is
+ currently unsupported.
"""
class TimestampGranularity(proto.Enum):
r"""Possible timestamp granularities to use when keeping multiple
versions of data in a table.
+
+ Values:
+ TIMESTAMP_GRANULARITY_UNSPECIFIED (0):
+ The user did not specify a granularity.
+ Should not be returned. When specified during
+ table creation, MILLIS will be used.
+ MILLIS (1):
+ The table keeps data versioned at a
+ granularity of 1ms.
"""
TIMESTAMP_GRANULARITY_UNSPECIFIED = 0
MILLIS = 1
class View(proto.Enum):
- r"""Defines a view over a table's fields."""
+ r"""Defines a view over a table's fields.
+
+ Values:
+ VIEW_UNSPECIFIED (0):
+ Uses the default view for each method as
+ documented in its request.
+ NAME_ONLY (1):
+ Only populates ``name``.
+ SCHEMA_VIEW (2):
+ Only populates ``name`` and fields related to the table's
+ schema.
+ REPLICATION_VIEW (3):
+ Only populates ``name`` and fields related to the table's
+ replication state.
+ ENCRYPTION_VIEW (5):
+ Only populates ``name`` and fields related to the table's
+ encryption state.
+ FULL (4):
+ Populates all fields.
+ """
VIEW_UNSPECIFIED = 0
NAME_ONLY = 1
SCHEMA_VIEW = 2
@@ -127,7 +285,7 @@ class ClusterState(proto.Message):
replication_state (google.cloud.bigtable_admin_v2.types.Table.ClusterState.ReplicationState):
Output only. The state of replication for the
table in this cluster.
- encryption_info (Sequence[google.cloud.bigtable_admin_v2.types.EncryptionInfo]):
+ encryption_info (MutableSequence[google.cloud.bigtable_admin_v2.types.EncryptionInfo]):
Output only. The encryption information for
the table in this cluster. If the encryption key
protecting this resource is customer managed,
@@ -139,7 +297,37 @@ class ClusterState(proto.Message):
"""
class ReplicationState(proto.Enum):
- r"""Table replication states."""
+ r"""Table replication states.
+
+ Values:
+ STATE_NOT_KNOWN (0):
+ The replication state of the table is unknown
+ in this cluster.
+ INITIALIZING (1):
+ The cluster was recently created, and the
+ table must finish copying over pre-existing data
+ from other clusters before it can begin
+ receiving live replication updates and serving
+ Data API requests.
+ PLANNED_MAINTENANCE (2):
+ The table is temporarily unable to serve Data
+ API requests from this cluster due to planned
+ internal maintenance.
+ UNPLANNED_MAINTENANCE (3):
+ The table is temporarily unable to serve Data
+ API requests from this cluster due to unplanned
+ or emergency maintenance.
+ READY (4):
+ The table can serve Data API requests from
+ this cluster. Depending on replication delay,
+ reads may not immediately reflect the state of
+ the table in other clusters.
+ READY_OPTIMIZING (5):
+ The table is fully created and ready for use after a
+ restore, and is being optimized for performance. When
+ optimizations are complete, the table will transition to
+ ``READY`` state.
+ """
STATE_NOT_KNOWN = 0
INITIALIZING = 1
PLANNED_MAINTENANCE = 2
@@ -147,43 +335,218 @@ class ReplicationState(proto.Enum):
READY = 4
READY_OPTIMIZING = 5
- replication_state = proto.Field(
+ replication_state: "Table.ClusterState.ReplicationState" = proto.Field(
proto.ENUM,
number=1,
enum="Table.ClusterState.ReplicationState",
)
- encryption_info = proto.RepeatedField(
+ encryption_info: MutableSequence["EncryptionInfo"] = proto.RepeatedField(
proto.MESSAGE,
number=2,
message="EncryptionInfo",
)
- name = proto.Field(
+ class AutomatedBackupPolicy(proto.Message):
+ r"""Defines an automated backup policy for a table
+
+ Attributes:
+ retention_period (google.protobuf.duration_pb2.Duration):
+ Required. How long the automated backups
+ should be retained. The only supported value at
+ this time is 3 days.
+ frequency (google.protobuf.duration_pb2.Duration):
+ Required. How frequently automated backups
+ should occur. The only supported value at this
+ time is 24 hours.
+ """
+
+ retention_period: duration_pb2.Duration = proto.Field(
+ proto.MESSAGE,
+ number=1,
+ message=duration_pb2.Duration,
+ )
+ frequency: duration_pb2.Duration = proto.Field(
+ proto.MESSAGE,
+ number=2,
+ message=duration_pb2.Duration,
+ )
+
+ name: str = proto.Field(
proto.STRING,
number=1,
)
- cluster_states = proto.MapField(
+ cluster_states: MutableMapping[str, ClusterState] = proto.MapField(
proto.STRING,
proto.MESSAGE,
number=2,
message=ClusterState,
)
- column_families = proto.MapField(
+ column_families: MutableMapping[str, "ColumnFamily"] = proto.MapField(
proto.STRING,
proto.MESSAGE,
number=3,
message="ColumnFamily",
)
- granularity = proto.Field(
+ granularity: TimestampGranularity = proto.Field(
proto.ENUM,
number=4,
enum=TimestampGranularity,
)
- restore_info = proto.Field(
+ restore_info: "RestoreInfo" = proto.Field(
proto.MESSAGE,
number=6,
message="RestoreInfo",
)
+ change_stream_config: "ChangeStreamConfig" = proto.Field(
+ proto.MESSAGE,
+ number=8,
+ message="ChangeStreamConfig",
+ )
+ deletion_protection: bool = proto.Field(
+ proto.BOOL,
+ number=9,
+ )
+ automated_backup_policy: AutomatedBackupPolicy = proto.Field(
+ proto.MESSAGE,
+ number=13,
+ oneof="automated_backup_config",
+ message=AutomatedBackupPolicy,
+ )
+ tiered_storage_config: "TieredStorageConfig" = proto.Field(
+ proto.MESSAGE,
+ number=14,
+ message="TieredStorageConfig",
+ )
+ row_key_schema: types.Type.Struct = proto.Field(
+ proto.MESSAGE,
+ number=15,
+ message=types.Type.Struct,
+ )
+
+
+class AuthorizedView(proto.Message):
+ r"""AuthorizedViews represent subsets of a particular Cloud
+ Bigtable table. Users can configure access to each Authorized
+ View independently from the table and use the existing Data APIs
+ to access the subset of data.
+
+
+ .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields
+
+ Attributes:
+ name (str):
+ Identifier. The name of this AuthorizedView. Values are of
+ the form
+ ``projects/{project}/instances/{instance}/tables/{table}/authorizedViews/{authorized_view}``
+ subset_view (google.cloud.bigtable_admin_v2.types.AuthorizedView.SubsetView):
+ An AuthorizedView permitting access to an
+ explicit subset of a Table.
+
+ This field is a member of `oneof`_ ``authorized_view``.
+ etag (str):
+ The etag for this AuthorizedView.
+ If this is provided on update, it must match the
+ server's etag. The server returns ABORTED error
+ on a mismatched etag.
+ deletion_protection (bool):
+ Set to true to make the AuthorizedView
+ protected against deletion. The parent Table and
+ containing Instance cannot be deleted if an
+ AuthorizedView has this bit set.
+ """
+
+ class ResponseView(proto.Enum):
+ r"""Defines a subset of an AuthorizedView's fields.
+
+ Values:
+ RESPONSE_VIEW_UNSPECIFIED (0):
+ Uses the default view for each method as
+ documented in the request.
+ NAME_ONLY (1):
+ Only populates ``name``.
+ BASIC (2):
+ Only populates the AuthorizedView's basic metadata. This
+ includes: name, deletion_protection, etag.
+ FULL (3):
+ Populates every fields.
+ """
+ RESPONSE_VIEW_UNSPECIFIED = 0
+ NAME_ONLY = 1
+ BASIC = 2
+ FULL = 3
+
+ class FamilySubsets(proto.Message):
+ r"""Subsets of a column family that are included in this
+ AuthorizedView.
+
+ Attributes:
+ qualifiers (MutableSequence[bytes]):
+ Individual exact column qualifiers to be
+ included in the AuthorizedView.
+ qualifier_prefixes (MutableSequence[bytes]):
+ Prefixes for qualifiers to be included in the
+ AuthorizedView. Every qualifier starting with
+ one of these prefixes is included in the
+ AuthorizedView. To provide access to all
+ qualifiers, include the empty string as a prefix
+ ("").
+ """
+
+ qualifiers: MutableSequence[bytes] = proto.RepeatedField(
+ proto.BYTES,
+ number=1,
+ )
+ qualifier_prefixes: MutableSequence[bytes] = proto.RepeatedField(
+ proto.BYTES,
+ number=2,
+ )
+
+ class SubsetView(proto.Message):
+ r"""Defines a simple AuthorizedView that is a subset of the
+ underlying Table.
+
+ Attributes:
+ row_prefixes (MutableSequence[bytes]):
+ Row prefixes to be included in the
+ AuthorizedView. To provide access to all rows,
+ include the empty string as a prefix ("").
+ family_subsets (MutableMapping[str, google.cloud.bigtable_admin_v2.types.AuthorizedView.FamilySubsets]):
+ Map from column family name to the columns in
+ this family to be included in the
+ AuthorizedView.
+ """
+
+ row_prefixes: MutableSequence[bytes] = proto.RepeatedField(
+ proto.BYTES,
+ number=1,
+ )
+ family_subsets: MutableMapping[
+ str, "AuthorizedView.FamilySubsets"
+ ] = proto.MapField(
+ proto.STRING,
+ proto.MESSAGE,
+ number=2,
+ message="AuthorizedView.FamilySubsets",
+ )
+
+ name: str = proto.Field(
+ proto.STRING,
+ number=1,
+ )
+ subset_view: SubsetView = proto.Field(
+ proto.MESSAGE,
+ number=2,
+ oneof="authorized_view",
+ message=SubsetView,
+ )
+ etag: str = proto.Field(
+ proto.STRING,
+ number=3,
+ )
+ deletion_protection: bool = proto.Field(
+ proto.BOOL,
+ number=4,
+ )
class ColumnFamily(proto.Message):
@@ -194,20 +557,40 @@ class ColumnFamily(proto.Message):
gc_rule (google.cloud.bigtable_admin_v2.types.GcRule):
Garbage collection rule specified as a
protobuf. Must serialize to at most 500 bytes.
+
NOTE: Garbage collection executes
opportunistically in the background, and so it's
possible for reads to return a cell even if it
matches the active GC expression for its family.
+ value_type (google.cloud.bigtable_admin_v2.types.Type):
+ The type of data stored in each of this family's cell
+ values, including its full encoding. If omitted, the family
+ only serves raw untyped bytes.
+
+ For now, only the ``Aggregate`` type is supported.
+
+ ``Aggregate`` can only be set at family creation and is
+ immutable afterwards.
+
+ If ``value_type`` is ``Aggregate``, written data must be
+ compatible with:
+
+ - ``value_type.input_type`` for ``AddInput`` mutations
"""
- gc_rule = proto.Field(
+ gc_rule: "GcRule" = proto.Field(
proto.MESSAGE,
number=1,
message="GcRule",
)
+ value_type: types.Type = proto.Field(
+ proto.MESSAGE,
+ number=3,
+ message=types.Type,
+ )
-class GcRule(proto.Message):
+class GcRule(oneof_message.OneofMessage):
r"""Rule for determining which cells to delete during garbage
collection.
@@ -247,12 +630,12 @@ class Intersection(proto.Message):
r"""A GcRule which deletes cells matching all of the given rules.
Attributes:
- rules (Sequence[google.cloud.bigtable_admin_v2.types.GcRule]):
+ rules (MutableSequence[google.cloud.bigtable_admin_v2.types.GcRule]):
Only delete cells which would be deleted by every element of
``rules``.
"""
- rules = proto.RepeatedField(
+ rules: MutableSequence["GcRule"] = proto.RepeatedField(
proto.MESSAGE,
number=1,
message="GcRule",
@@ -262,35 +645,35 @@ class Union(proto.Message):
r"""A GcRule which deletes cells matching any of the given rules.
Attributes:
- rules (Sequence[google.cloud.bigtable_admin_v2.types.GcRule]):
+ rules (MutableSequence[google.cloud.bigtable_admin_v2.types.GcRule]):
Delete cells which would be deleted by any element of
``rules``.
"""
- rules = proto.RepeatedField(
+ rules: MutableSequence["GcRule"] = proto.RepeatedField(
proto.MESSAGE,
number=1,
message="GcRule",
)
- max_num_versions = proto.Field(
+ max_num_versions: int = proto.Field(
proto.INT32,
number=1,
oneof="rule",
)
- max_age = proto.Field(
+ max_age: duration_pb2.Duration = proto.Field(
proto.MESSAGE,
number=2,
oneof="rule",
message=duration_pb2.Duration,
)
- intersection = proto.Field(
+ intersection: Intersection = proto.Field(
proto.MESSAGE,
number=3,
oneof="rule",
message=Intersection,
)
- union = proto.Field(
+ union: Union = proto.Field(
proto.MESSAGE,
number=4,
oneof="rule",
@@ -320,22 +703,41 @@ class EncryptionInfo(proto.Message):
"""
class EncryptionType(proto.Enum):
- r"""Possible encryption types for a resource."""
+ r"""Possible encryption types for a resource.
+
+ Values:
+ ENCRYPTION_TYPE_UNSPECIFIED (0):
+ Encryption type was not specified, though
+ data at rest remains encrypted.
+ GOOGLE_DEFAULT_ENCRYPTION (1):
+ The data backing this resource is encrypted
+ at rest with a key that is fully managed by
+ Google. No key version or status will be
+ populated. This is the default state.
+ CUSTOMER_MANAGED_ENCRYPTION (2):
+ The data backing this resource is encrypted at rest with a
+ key that is managed by the customer. The in-use version of
+ the key and its status are populated for CMEK-protected
+ tables. CMEK-protected backups are pinned to the key version
+ that was in use at the time the backup was taken. This key
+ version is populated but its status is not tracked and is
+ reported as ``UNKNOWN``.
+ """
ENCRYPTION_TYPE_UNSPECIFIED = 0
GOOGLE_DEFAULT_ENCRYPTION = 1
CUSTOMER_MANAGED_ENCRYPTION = 2
- encryption_type = proto.Field(
+ encryption_type: EncryptionType = proto.Field(
proto.ENUM,
number=3,
enum=EncryptionType,
)
- encryption_status = proto.Field(
+ encryption_status: status_pb2.Status = proto.Field(
proto.MESSAGE,
number=4,
message=status_pb2.Status,
)
- kms_key_version = proto.Field(
+ kms_key_version: str = proto.Field(
proto.STRING,
number=2,
)
@@ -345,6 +747,7 @@ class Snapshot(proto.Message):
r"""A snapshot of a table at a particular time. A snapshot can be
used as a checkpoint for data restoration or a data source for a
new table.
+
Note: This is a private alpha release of Cloud Bigtable
snapshots. This feature is not currently available to most Cloud
Bigtable customers. This feature might be changed in
@@ -353,8 +756,7 @@ class Snapshot(proto.Message):
Attributes:
name (str):
- Output only. The unique name of the snapshot. Values are of
- the form
+ The unique name of the snapshot. Values are of the form
``projects/{project}/instances/{instance}/clusters/{cluster}/snapshots/{snapshot}``.
source_table (google.cloud.bigtable_admin_v2.types.Table):
Output only. The source table at the time the
@@ -369,53 +771,66 @@ class Snapshot(proto.Message):
Output only. The time when the snapshot is
created.
delete_time (google.protobuf.timestamp_pb2.Timestamp):
- Output only. The time when the snapshot will
- be deleted. The maximum amount of time a
- snapshot can stay active is 365 days. If 'ttl'
- is not specified, the default maximum of 365
- days will be used.
+ The time when the snapshot will be deleted.
+ The maximum amount of time a snapshot can stay
+ active is 365 days. If 'ttl' is not specified,
+ the default maximum of 365 days will be used.
state (google.cloud.bigtable_admin_v2.types.Snapshot.State):
Output only. The current state of the
snapshot.
description (str):
- Output only. Description of the snapshot.
+ Description of the snapshot.
"""
class State(proto.Enum):
- r"""Possible states of a snapshot."""
+ r"""Possible states of a snapshot.
+
+ Values:
+ STATE_NOT_KNOWN (0):
+ The state of the snapshot could not be
+ determined.
+ READY (1):
+ The snapshot has been successfully created
+ and can serve all requests.
+ CREATING (2):
+ The snapshot is currently being created, and
+ may be destroyed if the creation process
+ encounters an error. A snapshot may not be
+ restored to a table while it is being created.
+ """
STATE_NOT_KNOWN = 0
READY = 1
CREATING = 2
- name = proto.Field(
+ name: str = proto.Field(
proto.STRING,
number=1,
)
- source_table = proto.Field(
+ source_table: "Table" = proto.Field(
proto.MESSAGE,
number=2,
message="Table",
)
- data_size_bytes = proto.Field(
+ data_size_bytes: int = proto.Field(
proto.INT64,
number=3,
)
- create_time = proto.Field(
+ create_time: timestamp_pb2.Timestamp = proto.Field(
proto.MESSAGE,
number=4,
message=timestamp_pb2.Timestamp,
)
- delete_time = proto.Field(
+ delete_time: timestamp_pb2.Timestamp = proto.Field(
proto.MESSAGE,
number=5,
message=timestamp_pb2.Timestamp,
)
- state = proto.Field(
+ state: State = proto.Field(
proto.ENUM,
number=6,
enum=State,
)
- description = proto.Field(
+ description: str = proto.Field(
proto.STRING,
number=7,
)
@@ -440,12 +855,23 @@ class Backup(proto.Message):
backup was created. This needs to be in the same instance as
the backup. Values are of the form
``projects/{project}/instances/{instance}/tables/{source_table}``.
+ source_backup (str):
+ Output only. Name of the backup from which
+ this backup was copied. If a backup is not
+ created by copying a backup, this field will be
+ empty. Values are of the form:
+
+ projects//instances//clusters//backups/
expire_time (google.protobuf.timestamp_pb2.Timestamp):
- Required. The expiration time of the backup, with
- microseconds granularity that must be at least 6 hours and
- at most 30 days from the time the request is received. Once
- the ``expire_time`` has passed, Cloud Bigtable will delete
- the backup and free the resources used by the backup.
+ Required. The expiration time of the backup. When creating a
+ backup or updating its ``expire_time``, the value must be
+ greater than the backup creation time by:
+
+ - At least 6 hours
+ - At most 90 days
+
+ Once the ``expire_time`` has passed, Cloud Bigtable will
+ delete the backup.
start_time (google.protobuf.timestamp_pb2.Timestamp):
Output only. ``start_time`` is the time that the backup was
started (i.e. approximately the time the
@@ -463,51 +889,111 @@ class Backup(proto.Message):
encryption_info (google.cloud.bigtable_admin_v2.types.EncryptionInfo):
Output only. The encryption information for
the backup.
+ backup_type (google.cloud.bigtable_admin_v2.types.Backup.BackupType):
+ Indicates the backup type of the backup.
+ hot_to_standard_time (google.protobuf.timestamp_pb2.Timestamp):
+ The time at which the hot backup will be converted to a
+ standard backup. Once the ``hot_to_standard_time`` has
+ passed, Cloud Bigtable will convert the hot backup to a
+ standard backup. This value must be greater than the backup
+ creation time by:
+
+ - At least 24 hours
+
+ This field only applies for hot backups. When creating or
+ updating a standard backup, attempting to set this field
+ will fail the request.
"""
class State(proto.Enum):
- r"""Indicates the current state of the backup."""
+ r"""Indicates the current state of the backup.
+
+ Values:
+ STATE_UNSPECIFIED (0):
+ Not specified.
+ CREATING (1):
+ The pending backup is still being created. Operations on the
+ backup may fail with ``FAILED_PRECONDITION`` in this state.
+ READY (2):
+ The backup is complete and ready for use.
+ """
STATE_UNSPECIFIED = 0
CREATING = 1
READY = 2
- name = proto.Field(
+ class BackupType(proto.Enum):
+ r"""The type of the backup.
+
+ Values:
+ BACKUP_TYPE_UNSPECIFIED (0):
+ Not specified.
+ STANDARD (1):
+ The default type for Cloud Bigtable managed
+ backups. Supported for backups created in both
+ HDD and SSD instances. Requires optimization
+ when restored to a table in an SSD instance.
+ HOT (2):
+ A backup type with faster restore to SSD
+ performance. Only supported for backups created
+ in SSD instances. A new SSD table restored from
+ a hot backup reaches production performance more
+ quickly than a standard backup.
+ """
+ BACKUP_TYPE_UNSPECIFIED = 0
+ STANDARD = 1
+ HOT = 2
+
+ name: str = proto.Field(
proto.STRING,
number=1,
)
- source_table = proto.Field(
+ source_table: str = proto.Field(
proto.STRING,
number=2,
)
- expire_time = proto.Field(
+ source_backup: str = proto.Field(
+ proto.STRING,
+ number=10,
+ )
+ expire_time: timestamp_pb2.Timestamp = proto.Field(
proto.MESSAGE,
number=3,
message=timestamp_pb2.Timestamp,
)
- start_time = proto.Field(
+ start_time: timestamp_pb2.Timestamp = proto.Field(
proto.MESSAGE,
number=4,
message=timestamp_pb2.Timestamp,
)
- end_time = proto.Field(
+ end_time: timestamp_pb2.Timestamp = proto.Field(
proto.MESSAGE,
number=5,
message=timestamp_pb2.Timestamp,
)
- size_bytes = proto.Field(
+ size_bytes: int = proto.Field(
proto.INT64,
number=6,
)
- state = proto.Field(
+ state: State = proto.Field(
proto.ENUM,
number=7,
enum=State,
)
- encryption_info = proto.Field(
+ encryption_info: "EncryptionInfo" = proto.Field(
proto.MESSAGE,
number=9,
message="EncryptionInfo",
)
+ backup_type: BackupType = proto.Field(
+ proto.ENUM,
+ number=11,
+ enum=BackupType,
+ )
+ hot_to_standard_time: timestamp_pb2.Timestamp = proto.Field(
+ proto.MESSAGE,
+ number=12,
+ message=timestamp_pb2.Timestamp,
+ )
class BackupInfo(proto.Message):
@@ -527,26 +1013,149 @@ class BackupInfo(proto.Message):
source_table (str):
Output only. Name of the table the backup was
created from.
+ source_backup (str):
+ Output only. Name of the backup from which
+ this backup was copied. If a backup is not
+ created by copying a backup, this field will be
+ empty. Values are of the form:
+
+ projects//instances//clusters//backups/
"""
- backup = proto.Field(
+ backup: str = proto.Field(
proto.STRING,
number=1,
)
- start_time = proto.Field(
+ start_time: timestamp_pb2.Timestamp = proto.Field(
proto.MESSAGE,
number=2,
message=timestamp_pb2.Timestamp,
)
- end_time = proto.Field(
+ end_time: timestamp_pb2.Timestamp = proto.Field(
proto.MESSAGE,
number=3,
message=timestamp_pb2.Timestamp,
)
- source_table = proto.Field(
+ source_table: str = proto.Field(
proto.STRING,
number=4,
)
+ source_backup: str = proto.Field(
+ proto.STRING,
+ number=10,
+ )
+
+
+class TieredStorageConfig(proto.Message):
+ r"""Config for tiered storage.
+ A valid config must have a valid TieredStorageRule. Otherwise
+ the whole TieredStorageConfig must be unset.
+ By default all data is stored in the SSD tier (only SSD
+ instances can configure tiered storage).
+
+ Attributes:
+ infrequent_access (google.cloud.bigtable_admin_v2.types.TieredStorageRule):
+ Rule to specify what data is stored in the
+ infrequent access(IA) tier. The IA tier allows
+ storing more data per node with reduced
+ performance.
+ """
+
+ infrequent_access: "TieredStorageRule" = proto.Field(
+ proto.MESSAGE,
+ number=1,
+ message="TieredStorageRule",
+ )
+
+
+class TieredStorageRule(proto.Message):
+ r"""Rule to specify what data is stored in a storage tier.
+
+ .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields
+
+ Attributes:
+ include_if_older_than (google.protobuf.duration_pb2.Duration):
+ Include cells older than the given age.
+ For the infrequent access tier, this value must
+ be at least 30 days.
+
+ This field is a member of `oneof`_ ``rule``.
+ """
+
+ include_if_older_than: duration_pb2.Duration = proto.Field(
+ proto.MESSAGE,
+ number=1,
+ oneof="rule",
+ message=duration_pb2.Duration,
+ )
+
+
+class ProtoSchema(proto.Message):
+ r"""Represents a protobuf schema.
+
+ Attributes:
+ proto_descriptors (bytes):
+ Required. Contains a protobuf-serialized
+ `google.protobuf.FileDescriptorSet `__,
+ which could include multiple proto files. To generate it,
+ `install `__ and
+ run ``protoc`` with ``--include_imports`` and
+ ``--descriptor_set_out``. For example, to generate for
+ moon/shot/app.proto, run
+
+ ::
+
+ $protoc --proto_path=/app_path --proto_path=/lib_path \
+ --include_imports \
+ --descriptor_set_out=descriptors.pb \
+ moon/shot/app.proto
+
+ For more details, see protobuffer `self
+ description `__.
+ """
+
+ proto_descriptors: bytes = proto.Field(
+ proto.BYTES,
+ number=2,
+ )
+
+
+class SchemaBundle(proto.Message):
+ r"""A named collection of related schemas.
+
+ .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields
+
+ Attributes:
+ name (str):
+ Identifier. The unique name identifying this schema bundle.
+ Values are of the form
+ ``projects/{project}/instances/{instance}/tables/{table}/schemaBundles/{schema_bundle}``
+ proto_schema (google.cloud.bigtable_admin_v2.types.ProtoSchema):
+ Schema for Protobufs.
+
+ This field is a member of `oneof`_ ``type``.
+ etag (str):
+ Optional. The etag for this schema bundle.
+ This may be sent on update and delete requests
+ to ensure the client has an up-to-date value
+ before proceeding. The server returns an ABORTED
+ error on a mismatched etag.
+ """
+
+ name: str = proto.Field(
+ proto.STRING,
+ number=1,
+ )
+ proto_schema: "ProtoSchema" = proto.Field(
+ proto.MESSAGE,
+ number=2,
+ oneof="type",
+ message="ProtoSchema",
+ )
+ etag: str = proto.Field(
+ proto.STRING,
+ number=3,
+ )
__all__ = tuple(sorted(__protobuf__.manifest))
diff --git a/google/cloud/bigtable_admin_v2/types/types.py b/google/cloud/bigtable_admin_v2/types/types.py
new file mode 100644
index 000000000..4f56429da
--- /dev/null
+++ b/google/cloud/bigtable_admin_v2/types/types.py
@@ -0,0 +1,841 @@
+# -*- coding: utf-8 -*-
+# Copyright 2025 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.
+#
+from __future__ import annotations
+
+from typing import MutableMapping, MutableSequence
+
+import proto # type: ignore
+
+
+__protobuf__ = proto.module(
+ package="google.bigtable.admin.v2",
+ manifest={
+ "Type",
+ },
+)
+
+
+class Type(proto.Message):
+ r"""``Type`` represents the type of data that is written to, read from,
+ or stored in Bigtable. It is heavily based on the GoogleSQL standard
+ to help maintain familiarity and consistency across products and
+ features.
+
+ For compatibility with Bigtable's existing untyped APIs, each
+ ``Type`` includes an ``Encoding`` which describes how to convert to
+ or from the underlying data.
+
+ Each encoding can operate in one of two modes:
+
+ - Sorted: In this mode, Bigtable guarantees that
+ ``Encode(X) <= Encode(Y)`` if and only if ``X <= Y``. This is
+ useful anywhere sort order is important, for example when encoding
+ keys.
+ - Distinct: In this mode, Bigtable guarantees that if ``X != Y``
+ then ``Encode(X) != Encode(Y)``. However, the converse is not
+ guaranteed. For example, both "{'foo': '1', 'bar': '2'}" and
+ "{'bar': '2', 'foo': '1'}" are valid encodings of the same JSON
+ value.
+
+ The API clearly documents which mode is used wherever an encoding
+ can be configured. Each encoding also documents which values are
+ supported in which modes. For example, when encoding INT64 as a
+ numeric STRING, negative numbers cannot be encoded in sorted mode.
+ This is because ``INT64(1) > INT64(-1)``, but
+ ``STRING("-00001") > STRING("00001")``.
+
+ This message has `oneof`_ fields (mutually exclusive fields).
+ For each oneof, at most one member field can be set at the same time.
+ Setting any member of the oneof automatically clears all other
+ members.
+
+ .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields
+
+ Attributes:
+ bytes_type (google.cloud.bigtable_admin_v2.types.Type.Bytes):
+ Bytes
+
+ This field is a member of `oneof`_ ``kind``.
+ string_type (google.cloud.bigtable_admin_v2.types.Type.String):
+ String
+
+ This field is a member of `oneof`_ ``kind``.
+ int64_type (google.cloud.bigtable_admin_v2.types.Type.Int64):
+ Int64
+
+ This field is a member of `oneof`_ ``kind``.
+ float32_type (google.cloud.bigtable_admin_v2.types.Type.Float32):
+ Float32
+
+ This field is a member of `oneof`_ ``kind``.
+ float64_type (google.cloud.bigtable_admin_v2.types.Type.Float64):
+ Float64
+
+ This field is a member of `oneof`_ ``kind``.
+ bool_type (google.cloud.bigtable_admin_v2.types.Type.Bool):
+ Bool
+
+ This field is a member of `oneof`_ ``kind``.
+ timestamp_type (google.cloud.bigtable_admin_v2.types.Type.Timestamp):
+ Timestamp
+
+ This field is a member of `oneof`_ ``kind``.
+ date_type (google.cloud.bigtable_admin_v2.types.Type.Date):
+ Date
+
+ This field is a member of `oneof`_ ``kind``.
+ aggregate_type (google.cloud.bigtable_admin_v2.types.Type.Aggregate):
+ Aggregate
+
+ This field is a member of `oneof`_ ``kind``.
+ struct_type (google.cloud.bigtable_admin_v2.types.Type.Struct):
+ Struct
+
+ This field is a member of `oneof`_ ``kind``.
+ array_type (google.cloud.bigtable_admin_v2.types.Type.Array):
+ Array
+
+ This field is a member of `oneof`_ ``kind``.
+ map_type (google.cloud.bigtable_admin_v2.types.Type.Map):
+ Map
+
+ This field is a member of `oneof`_ ``kind``.
+ proto_type (google.cloud.bigtable_admin_v2.types.Type.Proto):
+ Proto
+
+ This field is a member of `oneof`_ ``kind``.
+ enum_type (google.cloud.bigtable_admin_v2.types.Type.Enum):
+ Enum
+
+ This field is a member of `oneof`_ ``kind``.
+ """
+
+ class Bytes(proto.Message):
+ r"""Bytes Values of type ``Bytes`` are stored in ``Value.bytes_value``.
+
+ Attributes:
+ encoding (google.cloud.bigtable_admin_v2.types.Type.Bytes.Encoding):
+ The encoding to use when converting to or
+ from lower level types.
+ """
+
+ class Encoding(proto.Message):
+ r"""Rules used to convert to or from lower level types.
+
+ .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields
+
+ Attributes:
+ raw (google.cloud.bigtable_admin_v2.types.Type.Bytes.Encoding.Raw):
+ Use ``Raw`` encoding.
+
+ This field is a member of `oneof`_ ``encoding``.
+ """
+
+ class Raw(proto.Message):
+ r"""Leaves the value as-is.
+
+ Sorted mode: all values are supported.
+
+ Distinct mode: all values are supported.
+
+ """
+
+ raw: "Type.Bytes.Encoding.Raw" = proto.Field(
+ proto.MESSAGE,
+ number=1,
+ oneof="encoding",
+ message="Type.Bytes.Encoding.Raw",
+ )
+
+ encoding: "Type.Bytes.Encoding" = proto.Field(
+ proto.MESSAGE,
+ number=1,
+ message="Type.Bytes.Encoding",
+ )
+
+ class String(proto.Message):
+ r"""String Values of type ``String`` are stored in
+ ``Value.string_value``.
+
+ Attributes:
+ encoding (google.cloud.bigtable_admin_v2.types.Type.String.Encoding):
+ The encoding to use when converting to or
+ from lower level types.
+ """
+
+ class Encoding(proto.Message):
+ r"""Rules used to convert to or from lower level types.
+
+ This message has `oneof`_ fields (mutually exclusive fields).
+ For each oneof, at most one member field can be set at the same time.
+ Setting any member of the oneof automatically clears all other
+ members.
+
+ .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields
+
+ Attributes:
+ utf8_raw (google.cloud.bigtable_admin_v2.types.Type.String.Encoding.Utf8Raw):
+ Deprecated: if set, converts to an empty ``utf8_bytes``.
+
+ This field is a member of `oneof`_ ``encoding``.
+ utf8_bytes (google.cloud.bigtable_admin_v2.types.Type.String.Encoding.Utf8Bytes):
+ Use ``Utf8Bytes`` encoding.
+
+ This field is a member of `oneof`_ ``encoding``.
+ """
+
+ class Utf8Raw(proto.Message):
+ r"""Deprecated: prefer the equivalent ``Utf8Bytes``."""
+
+ class Utf8Bytes(proto.Message):
+ r"""UTF-8 encoding.
+
+ Sorted mode:
+
+ - All values are supported.
+ - Code point order is preserved.
+
+ Distinct mode: all values are supported.
+
+ Compatible with:
+
+ - BigQuery ``TEXT`` encoding
+ - HBase ``Bytes.toBytes``
+ - Java ``String#getBytes(StandardCharsets.UTF_8)``
+
+ """
+
+ utf8_raw: "Type.String.Encoding.Utf8Raw" = proto.Field(
+ proto.MESSAGE,
+ number=1,
+ oneof="encoding",
+ message="Type.String.Encoding.Utf8Raw",
+ )
+ utf8_bytes: "Type.String.Encoding.Utf8Bytes" = proto.Field(
+ proto.MESSAGE,
+ number=2,
+ oneof="encoding",
+ message="Type.String.Encoding.Utf8Bytes",
+ )
+
+ encoding: "Type.String.Encoding" = proto.Field(
+ proto.MESSAGE,
+ number=1,
+ message="Type.String.Encoding",
+ )
+
+ class Int64(proto.Message):
+ r"""Int64 Values of type ``Int64`` are stored in ``Value.int_value``.
+
+ Attributes:
+ encoding (google.cloud.bigtable_admin_v2.types.Type.Int64.Encoding):
+ The encoding to use when converting to or
+ from lower level types.
+ """
+
+ class Encoding(proto.Message):
+ r"""Rules used to convert to or from lower level types.
+
+ This message has `oneof`_ fields (mutually exclusive fields).
+ For each oneof, at most one member field can be set at the same time.
+ Setting any member of the oneof automatically clears all other
+ members.
+
+ .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields
+
+ Attributes:
+ big_endian_bytes (google.cloud.bigtable_admin_v2.types.Type.Int64.Encoding.BigEndianBytes):
+ Use ``BigEndianBytes`` encoding.
+
+ This field is a member of `oneof`_ ``encoding``.
+ ordered_code_bytes (google.cloud.bigtable_admin_v2.types.Type.Int64.Encoding.OrderedCodeBytes):
+ Use ``OrderedCodeBytes`` encoding.
+
+ This field is a member of `oneof`_ ``encoding``.
+ """
+
+ class BigEndianBytes(proto.Message):
+ r"""Encodes the value as an 8-byte big-endian two's complement value.
+
+ Sorted mode: non-negative values are supported.
+
+ Distinct mode: all values are supported.
+
+ Compatible with:
+
+ - BigQuery ``BINARY`` encoding
+ - HBase ``Bytes.toBytes``
+ - Java ``ByteBuffer.putLong()`` with ``ByteOrder.BIG_ENDIAN``
+
+ Attributes:
+ bytes_type (google.cloud.bigtable_admin_v2.types.Type.Bytes):
+ Deprecated: ignored if set.
+ """
+
+ bytes_type: "Type.Bytes" = proto.Field(
+ proto.MESSAGE,
+ number=1,
+ message="Type.Bytes",
+ )
+
+ class OrderedCodeBytes(proto.Message):
+ r"""Encodes the value in a variable length binary format of up to
+ 10 bytes. Values that are closer to zero use fewer bytes.
+
+ Sorted mode: all values are supported.
+
+ Distinct mode: all values are supported.
+
+ """
+
+ big_endian_bytes: "Type.Int64.Encoding.BigEndianBytes" = proto.Field(
+ proto.MESSAGE,
+ number=1,
+ oneof="encoding",
+ message="Type.Int64.Encoding.BigEndianBytes",
+ )
+ ordered_code_bytes: "Type.Int64.Encoding.OrderedCodeBytes" = proto.Field(
+ proto.MESSAGE,
+ number=2,
+ oneof="encoding",
+ message="Type.Int64.Encoding.OrderedCodeBytes",
+ )
+
+ encoding: "Type.Int64.Encoding" = proto.Field(
+ proto.MESSAGE,
+ number=1,
+ message="Type.Int64.Encoding",
+ )
+
+ class Bool(proto.Message):
+ r"""bool Values of type ``Bool`` are stored in ``Value.bool_value``."""
+
+ class Float32(proto.Message):
+ r"""Float32 Values of type ``Float32`` are stored in
+ ``Value.float_value``.
+
+ """
+
+ class Float64(proto.Message):
+ r"""Float64 Values of type ``Float64`` are stored in
+ ``Value.float_value``.
+
+ """
+
+ class Timestamp(proto.Message):
+ r"""Timestamp Values of type ``Timestamp`` are stored in
+ ``Value.timestamp_value``.
+
+ Attributes:
+ encoding (google.cloud.bigtable_admin_v2.types.Type.Timestamp.Encoding):
+ The encoding to use when converting to or
+ from lower level types.
+ """
+
+ class Encoding(proto.Message):
+ r"""Rules used to convert to or from lower level types.
+
+ .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields
+
+ Attributes:
+ unix_micros_int64 (google.cloud.bigtable_admin_v2.types.Type.Int64.Encoding):
+ Encodes the number of microseconds since the Unix epoch
+ using the given ``Int64`` encoding. Values must be
+ microsecond-aligned.
+
+ Compatible with:
+
+ - Java ``Instant.truncatedTo()`` with ``ChronoUnit.MICROS``
+
+ This field is a member of `oneof`_ ``encoding``.
+ """
+
+ unix_micros_int64: "Type.Int64.Encoding" = proto.Field(
+ proto.MESSAGE,
+ number=1,
+ oneof="encoding",
+ message="Type.Int64.Encoding",
+ )
+
+ encoding: "Type.Timestamp.Encoding" = proto.Field(
+ proto.MESSAGE,
+ number=1,
+ message="Type.Timestamp.Encoding",
+ )
+
+ class Date(proto.Message):
+ r"""Date Values of type ``Date`` are stored in ``Value.date_value``."""
+
+ class Struct(proto.Message):
+ r"""A structured data value, consisting of fields which map to
+ dynamically typed values. Values of type ``Struct`` are stored in
+ ``Value.array_value`` where entries are in the same order and number
+ as ``field_types``.
+
+ Attributes:
+ fields (MutableSequence[google.cloud.bigtable_admin_v2.types.Type.Struct.Field]):
+ The names and types of the fields in this
+ struct.
+ encoding (google.cloud.bigtable_admin_v2.types.Type.Struct.Encoding):
+ The encoding to use when converting to or
+ from lower level types.
+ """
+
+ class Field(proto.Message):
+ r"""A struct field and its type.
+
+ Attributes:
+ field_name (str):
+ The field name (optional). Fields without a ``field_name``
+ are considered anonymous and cannot be referenced by name.
+ type_ (google.cloud.bigtable_admin_v2.types.Type):
+ The type of values in this field.
+ """
+
+ field_name: str = proto.Field(
+ proto.STRING,
+ number=1,
+ )
+ type_: "Type" = proto.Field(
+ proto.MESSAGE,
+ number=2,
+ message="Type",
+ )
+
+ class Encoding(proto.Message):
+ r"""Rules used to convert to or from lower level types.
+
+ This message has `oneof`_ fields (mutually exclusive fields).
+ For each oneof, at most one member field can be set at the same time.
+ Setting any member of the oneof automatically clears all other
+ members.
+
+ .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields
+
+ Attributes:
+ singleton (google.cloud.bigtable_admin_v2.types.Type.Struct.Encoding.Singleton):
+ Use ``Singleton`` encoding.
+
+ This field is a member of `oneof`_ ``encoding``.
+ delimited_bytes (google.cloud.bigtable_admin_v2.types.Type.Struct.Encoding.DelimitedBytes):
+ Use ``DelimitedBytes`` encoding.
+
+ This field is a member of `oneof`_ ``encoding``.
+ ordered_code_bytes (google.cloud.bigtable_admin_v2.types.Type.Struct.Encoding.OrderedCodeBytes):
+ User ``OrderedCodeBytes`` encoding.
+
+ This field is a member of `oneof`_ ``encoding``.
+ """
+
+ class Singleton(proto.Message):
+ r"""Uses the encoding of ``fields[0].type`` as-is. Only valid if
+ ``fields.size == 1``.
+
+ """
+
+ class DelimitedBytes(proto.Message):
+ r"""Fields are encoded independently and concatenated with a
+ configurable ``delimiter`` in between.
+
+ A struct with no fields defined is encoded as a single
+ ``delimiter``.
+
+ Sorted mode:
+
+ - Fields are encoded in sorted mode.
+ - Encoded field values must not contain any bytes <=
+ ``delimiter[0]``
+ - Element-wise order is preserved: ``A < B`` if ``A[0] < B[0]``, or
+ if ``A[0] == B[0] && A[1] < B[1]``, etc. Strict prefixes sort
+ first.
+
+ Distinct mode:
+
+ - Fields are encoded in distinct mode.
+ - Encoded field values must not contain ``delimiter[0]``.
+
+ Attributes:
+ delimiter (bytes):
+ Byte sequence used to delimit concatenated
+ fields. The delimiter must contain at least 1
+ character and at most 50 characters.
+ """
+
+ delimiter: bytes = proto.Field(
+ proto.BYTES,
+ number=1,
+ )
+
+ class OrderedCodeBytes(proto.Message):
+ r"""Fields are encoded independently and concatenated with the fixed
+ byte pair {0x00, 0x01} in between.
+
+ Any null (0x00) byte in an encoded field is replaced by the fixed
+ byte pair {0x00, 0xFF}.
+
+ Fields that encode to the empty string "" have special handling:
+
+ - If *every* field encodes to "", or if the STRUCT has no fields
+ defined, then the STRUCT is encoded as the fixed byte pair {0x00,
+ 0x00}.
+ - Otherwise, the STRUCT only encodes until the last non-empty field,
+ omitting any trailing empty fields. Any empty fields that aren't
+ omitted are replaced with the fixed byte pair {0x00, 0x00}.
+
+ Examples:
+
+ - STRUCT() -> "\\00\\00"
+ - STRUCT("") -> "\\00\\00"
+ - STRUCT("", "") -> "\\00\\00"
+ - STRUCT("", "B") -> "\\00\\00" + "\\00\\01" + "B"
+ - STRUCT("A", "") -> "A"
+ - STRUCT("", "B", "") -> "\\00\\00" + "\\00\\01" + "B"
+ - STRUCT("A", "", "C") -> "A" + "\\00\\01" + "\\00\\00" + "\\00\\01"
+ + "C"
+
+ Since null bytes are always escaped, this encoding can cause size
+ blowup for encodings like ``Int64.BigEndianBytes`` that are likely
+ to produce many such bytes.
+
+ Sorted mode:
+
+ - Fields are encoded in sorted mode.
+ - All values supported by the field encodings are allowed
+ - Element-wise order is preserved: ``A < B`` if ``A[0] < B[0]``, or
+ if ``A[0] == B[0] && A[1] < B[1]``, etc. Strict prefixes sort
+ first.
+
+ Distinct mode:
+
+ - Fields are encoded in distinct mode.
+ - All values supported by the field encodings are allowed.
+
+ """
+
+ singleton: "Type.Struct.Encoding.Singleton" = proto.Field(
+ proto.MESSAGE,
+ number=1,
+ oneof="encoding",
+ message="Type.Struct.Encoding.Singleton",
+ )
+ delimited_bytes: "Type.Struct.Encoding.DelimitedBytes" = proto.Field(
+ proto.MESSAGE,
+ number=2,
+ oneof="encoding",
+ message="Type.Struct.Encoding.DelimitedBytes",
+ )
+ ordered_code_bytes: "Type.Struct.Encoding.OrderedCodeBytes" = proto.Field(
+ proto.MESSAGE,
+ number=3,
+ oneof="encoding",
+ message="Type.Struct.Encoding.OrderedCodeBytes",
+ )
+
+ fields: MutableSequence["Type.Struct.Field"] = proto.RepeatedField(
+ proto.MESSAGE,
+ number=1,
+ message="Type.Struct.Field",
+ )
+ encoding: "Type.Struct.Encoding" = proto.Field(
+ proto.MESSAGE,
+ number=2,
+ message="Type.Struct.Encoding",
+ )
+
+ class Proto(proto.Message):
+ r"""A protobuf message type. Values of type ``Proto`` are stored in
+ ``Value.bytes_value``.
+
+ Attributes:
+ schema_bundle_id (str):
+ The ID of the schema bundle that this proto
+ is defined in.
+ message_name (str):
+ The fully qualified name of the protobuf
+ message, including package. In the format of
+ "foo.bar.Message".
+ """
+
+ schema_bundle_id: str = proto.Field(
+ proto.STRING,
+ number=1,
+ )
+ message_name: str = proto.Field(
+ proto.STRING,
+ number=2,
+ )
+
+ class Enum(proto.Message):
+ r"""A protobuf enum type. Values of type ``Enum`` are stored in
+ ``Value.int_value``.
+
+ Attributes:
+ schema_bundle_id (str):
+ The ID of the schema bundle that this enum is
+ defined in.
+ enum_name (str):
+ The fully qualified name of the protobuf enum
+ message, including package. In the format of
+ "foo.bar.EnumMessage".
+ """
+
+ schema_bundle_id: str = proto.Field(
+ proto.STRING,
+ number=1,
+ )
+ enum_name: str = proto.Field(
+ proto.STRING,
+ number=2,
+ )
+
+ class Array(proto.Message):
+ r"""An ordered list of elements of a given type. Values of type
+ ``Array`` are stored in ``Value.array_value``.
+
+ Attributes:
+ element_type (google.cloud.bigtable_admin_v2.types.Type):
+ The type of the elements in the array. This must not be
+ ``Array``.
+ """
+
+ element_type: "Type" = proto.Field(
+ proto.MESSAGE,
+ number=1,
+ message="Type",
+ )
+
+ class Map(proto.Message):
+ r"""A mapping of keys to values of a given type. Values of type ``Map``
+ are stored in a ``Value.array_value`` where each entry is another
+ ``Value.array_value`` with two elements (the key and the value, in
+ that order). Normally encoded Map values won't have repeated keys,
+ however, clients are expected to handle the case in which they do.
+ If the same key appears multiple times, the *last* value takes
+ precedence.
+
+ Attributes:
+ key_type (google.cloud.bigtable_admin_v2.types.Type):
+ The type of a map key. Only ``Bytes``, ``String``, and
+ ``Int64`` are allowed as key types.
+ value_type (google.cloud.bigtable_admin_v2.types.Type):
+ The type of the values in a map.
+ """
+
+ key_type: "Type" = proto.Field(
+ proto.MESSAGE,
+ number=1,
+ message="Type",
+ )
+ value_type: "Type" = proto.Field(
+ proto.MESSAGE,
+ number=2,
+ message="Type",
+ )
+
+ class Aggregate(proto.Message):
+ r"""A value that combines incremental updates into a summarized value.
+
+ Data is never directly written or read using type ``Aggregate``.
+ Writes will provide either the ``input_type`` or ``state_type``, and
+ reads will always return the ``state_type`` .
+
+ This message has `oneof`_ fields (mutually exclusive fields).
+ For each oneof, at most one member field can be set at the same time.
+ Setting any member of the oneof automatically clears all other
+ members.
+
+ .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields
+
+ Attributes:
+ input_type (google.cloud.bigtable_admin_v2.types.Type):
+ Type of the inputs that are accumulated by this
+ ``Aggregate``, which must specify a full encoding. Use
+ ``AddInput`` mutations to accumulate new inputs.
+ state_type (google.cloud.bigtable_admin_v2.types.Type):
+ Output only. Type that holds the internal accumulator state
+ for the ``Aggregate``. This is a function of the
+ ``input_type`` and ``aggregator`` chosen, and will always
+ specify a full encoding.
+ sum (google.cloud.bigtable_admin_v2.types.Type.Aggregate.Sum):
+ Sum aggregator.
+
+ This field is a member of `oneof`_ ``aggregator``.
+ hllpp_unique_count (google.cloud.bigtable_admin_v2.types.Type.Aggregate.HyperLogLogPlusPlusUniqueCount):
+ HyperLogLogPlusPlusUniqueCount aggregator.
+
+ This field is a member of `oneof`_ ``aggregator``.
+ max_ (google.cloud.bigtable_admin_v2.types.Type.Aggregate.Max):
+ Max aggregator.
+
+ This field is a member of `oneof`_ ``aggregator``.
+ min_ (google.cloud.bigtable_admin_v2.types.Type.Aggregate.Min):
+ Min aggregator.
+
+ This field is a member of `oneof`_ ``aggregator``.
+ """
+
+ class Sum(proto.Message):
+ r"""Computes the sum of the input values. Allowed input: ``Int64``
+ State: same as input
+
+ """
+
+ class Max(proto.Message):
+ r"""Computes the max of the input values. Allowed input: ``Int64``
+ State: same as input
+
+ """
+
+ class Min(proto.Message):
+ r"""Computes the min of the input values. Allowed input: ``Int64``
+ State: same as input
+
+ """
+
+ class HyperLogLogPlusPlusUniqueCount(proto.Message):
+ r"""Computes an approximate unique count over the input values. When
+ using raw data as input, be careful to use a consistent encoding.
+ Otherwise the same value encoded differently could count more than
+ once, or two distinct values could count as identical. Input: Any,
+ or omit for Raw State: TBD Special state conversions: ``Int64`` (the
+ unique count estimate)
+
+ """
+
+ input_type: "Type" = proto.Field(
+ proto.MESSAGE,
+ number=1,
+ message="Type",
+ )
+ state_type: "Type" = proto.Field(
+ proto.MESSAGE,
+ number=2,
+ message="Type",
+ )
+ sum: "Type.Aggregate.Sum" = proto.Field(
+ proto.MESSAGE,
+ number=4,
+ oneof="aggregator",
+ message="Type.Aggregate.Sum",
+ )
+ hllpp_unique_count: "Type.Aggregate.HyperLogLogPlusPlusUniqueCount" = (
+ proto.Field(
+ proto.MESSAGE,
+ number=5,
+ oneof="aggregator",
+ message="Type.Aggregate.HyperLogLogPlusPlusUniqueCount",
+ )
+ )
+ max_: "Type.Aggregate.Max" = proto.Field(
+ proto.MESSAGE,
+ number=6,
+ oneof="aggregator",
+ message="Type.Aggregate.Max",
+ )
+ min_: "Type.Aggregate.Min" = proto.Field(
+ proto.MESSAGE,
+ number=7,
+ oneof="aggregator",
+ message="Type.Aggregate.Min",
+ )
+
+ bytes_type: Bytes = proto.Field(
+ proto.MESSAGE,
+ number=1,
+ oneof="kind",
+ message=Bytes,
+ )
+ string_type: String = proto.Field(
+ proto.MESSAGE,
+ number=2,
+ oneof="kind",
+ message=String,
+ )
+ int64_type: Int64 = proto.Field(
+ proto.MESSAGE,
+ number=5,
+ oneof="kind",
+ message=Int64,
+ )
+ float32_type: Float32 = proto.Field(
+ proto.MESSAGE,
+ number=12,
+ oneof="kind",
+ message=Float32,
+ )
+ float64_type: Float64 = proto.Field(
+ proto.MESSAGE,
+ number=9,
+ oneof="kind",
+ message=Float64,
+ )
+ bool_type: Bool = proto.Field(
+ proto.MESSAGE,
+ number=8,
+ oneof="kind",
+ message=Bool,
+ )
+ timestamp_type: Timestamp = proto.Field(
+ proto.MESSAGE,
+ number=10,
+ oneof="kind",
+ message=Timestamp,
+ )
+ date_type: Date = proto.Field(
+ proto.MESSAGE,
+ number=11,
+ oneof="kind",
+ message=Date,
+ )
+ aggregate_type: Aggregate = proto.Field(
+ proto.MESSAGE,
+ number=6,
+ oneof="kind",
+ message=Aggregate,
+ )
+ struct_type: Struct = proto.Field(
+ proto.MESSAGE,
+ number=7,
+ oneof="kind",
+ message=Struct,
+ )
+ array_type: Array = proto.Field(
+ proto.MESSAGE,
+ number=3,
+ oneof="kind",
+ message=Array,
+ )
+ map_type: Map = proto.Field(
+ proto.MESSAGE,
+ number=4,
+ oneof="kind",
+ message=Map,
+ )
+ proto_type: Proto = proto.Field(
+ proto.MESSAGE,
+ number=13,
+ oneof="kind",
+ message=Proto,
+ )
+ enum_type: Enum = proto.Field(
+ proto.MESSAGE,
+ number=14,
+ oneof="kind",
+ message=Enum,
+ )
+
+
+__all__ = tuple(sorted(__protobuf__.manifest))
diff --git a/google/cloud/bigtable_admin_v2/utils/__init__.py b/google/cloud/bigtable_admin_v2/utils/__init__.py
new file mode 100644
index 000000000..93d766056
--- /dev/null
+++ b/google/cloud/bigtable_admin_v2/utils/__init__.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+# Copyright 2025 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.
+#
+# This directory is a directory for handwritten code, made for inserting
+# specifically the oneof_message module into files in the autogenerated
+# types directory without causing ImportErrors due to circular imports.
+# For other use cases, use the overlay submodule.
diff --git a/google/cloud/bigtable_admin_v2/utils/oneof_message.py b/google/cloud/bigtable_admin_v2/utils/oneof_message.py
new file mode 100644
index 000000000..e110d8fa6
--- /dev/null
+++ b/google/cloud/bigtable_admin_v2/utils/oneof_message.py
@@ -0,0 +1,108 @@
+# -*- coding: utf-8 -*-
+# Copyright 2025 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 collections.abc
+import proto
+
+
+class OneofMessage(proto.Message):
+ def _get_oneof_field_from_key(self, key):
+ """Given a field name, return the corresponding oneof associated with it. If it doesn't exist, return None."""
+
+ oneof_type = None
+
+ try:
+ oneof_type = self._meta.fields[key].oneof
+ except KeyError:
+ # Underscores may be appended to field names
+ # that collide with python or proto-plus keywords.
+ # In case a key only exists with a `_` suffix, coerce the key
+ # to include the `_` suffix. It's not possible to
+ # natively define the same field with a trailing underscore in protobuf.
+ # See related issue
+ # https://github.com/googleapis/python-api-core/issues/227
+ if f"{key}_" in self._meta.fields:
+ key = f"{key}_"
+ oneof_type = self._meta.fields[key].oneof
+
+ return oneof_type
+
+ def __init__(
+ self,
+ mapping=None,
+ *,
+ ignore_unknown_fields=False,
+ **kwargs,
+ ):
+ # We accept several things for `mapping`:
+ # * An instance of this class.
+ # * An instance of the underlying protobuf descriptor class.
+ # * A dict
+ # * Nothing (keyword arguments only).
+ #
+ #
+ # Check for oneofs collisions in the parameters provided. Extract a set of
+ # all fields that are set from the mappings + kwargs combined.
+ mapping_fields = set(kwargs.keys())
+
+ if mapping is None:
+ pass
+ elif isinstance(mapping, collections.abc.Mapping):
+ mapping_fields.update(mapping.keys())
+ elif isinstance(mapping, self._meta.pb):
+ mapping_fields.update(field.name for field, _ in mapping.ListFields())
+ elif isinstance(mapping, type(self)):
+ mapping_fields.update(field.name for field, _ in mapping._pb.ListFields())
+ else:
+ # Sanity check: Did we get something not a map? Error if so.
+ raise TypeError(
+ "Invalid constructor input for %s: %r"
+ % (
+ self.__class__.__name__,
+ mapping,
+ )
+ )
+
+ oneofs = set()
+
+ for field in mapping_fields:
+ oneof_field = self._get_oneof_field_from_key(field)
+ if oneof_field is not None:
+ if oneof_field in oneofs:
+ raise ValueError(
+ "Invalid constructor input for %s: Multiple fields defined for oneof %s"
+ % (self.__class__.__name__, oneof_field)
+ )
+ else:
+ oneofs.add(oneof_field)
+
+ super().__init__(mapping, ignore_unknown_fields=ignore_unknown_fields, **kwargs)
+
+ def __setattr__(self, key, value):
+ # Oneof check: Only set the value of an existing oneof field
+ # if the field being overridden is the same as the field already set
+ # for the oneof.
+ oneof = self._get_oneof_field_from_key(key)
+ if (
+ oneof is not None
+ and self._pb.HasField(oneof)
+ and self._pb.WhichOneof(oneof) != key
+ ):
+ raise ValueError(
+ "Overriding the field set for oneof %s with a different field %s"
+ % (oneof, key)
+ )
+ super().__setattr__(key, value)
diff --git a/google/cloud/bigtable_v2/__init__.py b/google/cloud/bigtable_v2/__init__.py
index d744bd53f..ec552a85d 100644
--- a/google/cloud/bigtable_v2/__init__.py
+++ b/google/cloud/bigtable_v2/__init__.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -13,64 +13,232 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+from google.cloud.bigtable_v2 import gapic_version as package_version
+
+import google.api_core as api_core
+import sys
+
+__version__ = package_version.__version__
+
+if sys.version_info >= (3, 8): # pragma: NO COVER
+ from importlib import metadata
+else: # pragma: NO COVER
+ # TODO(https://github.com/googleapis/python-api-core/issues/835): Remove
+ # this code path once we drop support for Python 3.7
+ import importlib_metadata as metadata
+
from .services.bigtable import BigtableClient
from .services.bigtable import BigtableAsyncClient
from .types.bigtable import CheckAndMutateRowRequest
from .types.bigtable import CheckAndMutateRowResponse
+from .types.bigtable import ExecuteQueryRequest
+from .types.bigtable import ExecuteQueryResponse
+from .types.bigtable import GenerateInitialChangeStreamPartitionsRequest
+from .types.bigtable import GenerateInitialChangeStreamPartitionsResponse
from .types.bigtable import MutateRowRequest
from .types.bigtable import MutateRowResponse
from .types.bigtable import MutateRowsRequest
from .types.bigtable import MutateRowsResponse
from .types.bigtable import PingAndWarmRequest
from .types.bigtable import PingAndWarmResponse
+from .types.bigtable import PrepareQueryRequest
+from .types.bigtable import PrepareQueryResponse
+from .types.bigtable import RateLimitInfo
+from .types.bigtable import ReadChangeStreamRequest
+from .types.bigtable import ReadChangeStreamResponse
from .types.bigtable import ReadModifyWriteRowRequest
from .types.bigtable import ReadModifyWriteRowResponse
from .types.bigtable import ReadRowsRequest
from .types.bigtable import ReadRowsResponse
from .types.bigtable import SampleRowKeysRequest
from .types.bigtable import SampleRowKeysResponse
+from .types.data import ArrayValue
from .types.data import Cell
from .types.data import Column
+from .types.data import ColumnMetadata
from .types.data import ColumnRange
from .types.data import Family
+from .types.data import Idempotency
from .types.data import Mutation
+from .types.data import PartialResultSet
+from .types.data import ProtoFormat
+from .types.data import ProtoRows
+from .types.data import ProtoRowsBatch
+from .types.data import ProtoSchema
from .types.data import ReadModifyWriteRule
+from .types.data import ResultSetMetadata
from .types.data import Row
from .types.data import RowFilter
from .types.data import RowRange
from .types.data import RowSet
+from .types.data import StreamContinuationToken
+from .types.data import StreamContinuationTokens
+from .types.data import StreamPartition
from .types.data import TimestampRange
+from .types.data import Value
from .types.data import ValueRange
+from .types.feature_flags import FeatureFlags
+from .types.peer_info import PeerInfo
+from .types.request_stats import FullReadStatsView
+from .types.request_stats import ReadIterationStats
+from .types.request_stats import RequestLatencyStats
+from .types.request_stats import RequestStats
+from .types.response_params import ResponseParams
+from .types.types import Type
+
+if hasattr(api_core, "check_python_version") and hasattr(
+ api_core, "check_dependency_versions"
+): # pragma: NO COVER
+ api_core.check_python_version("google.cloud.bigtable_v2") # type: ignore
+ api_core.check_dependency_versions("google.cloud.bigtable_v2") # type: ignore
+else: # pragma: NO COVER
+ # An older version of api_core is installed which does not define the
+ # functions above. We do equivalent checks manually.
+ try:
+ import warnings
+ import sys
+
+ _py_version_str = sys.version.split()[0]
+ _package_label = "google.cloud.bigtable_v2"
+ if sys.version_info < (3, 9):
+ warnings.warn(
+ "You are using a non-supported Python version "
+ + f"({_py_version_str}). Google will not post any further "
+ + f"updates to {_package_label} supporting this Python version. "
+ + "Please upgrade to the latest Python version, or at "
+ + f"least to Python 3.9, and then update {_package_label}.",
+ FutureWarning,
+ )
+ if sys.version_info[:2] == (3, 9):
+ warnings.warn(
+ f"You are using a Python version ({_py_version_str}) "
+ + f"which Google will stop supporting in {_package_label} in "
+ + "January 2026. Please "
+ + "upgrade to the latest Python version, or at "
+ + "least to Python 3.10, before then, and "
+ + f"then update {_package_label}.",
+ FutureWarning,
+ )
+
+ def parse_version_to_tuple(version_string: str):
+ """Safely converts a semantic version string to a comparable tuple of integers.
+ Example: "4.25.8" -> (4, 25, 8)
+ Ignores non-numeric parts and handles common version formats.
+ Args:
+ version_string: Version string in the format "x.y.z" or "x.y.z"
+ Returns:
+ Tuple of integers for the parsed version string.
+ """
+ parts = []
+ for part in version_string.split("."):
+ try:
+ parts.append(int(part))
+ except ValueError:
+ # If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here.
+ # This is a simplification compared to 'packaging.parse_version', but sufficient
+ # for comparing strictly numeric semantic versions.
+ break
+ return tuple(parts)
+
+ def _get_version(dependency_name):
+ try:
+ version_string: str = metadata.version(dependency_name)
+ parsed_version = parse_version_to_tuple(version_string)
+ return (parsed_version, version_string)
+ except Exception:
+ # Catch exceptions from metadata.version() (e.g., PackageNotFoundError)
+ # or errors during parse_version_to_tuple
+ return (None, "--")
+
+ _dependency_package = "google.protobuf"
+ _next_supported_version = "4.25.8"
+ _next_supported_version_tuple = (4, 25, 8)
+ _recommendation = " (we recommend 6.x)"
+ (_version_used, _version_used_string) = _get_version(_dependency_package)
+ if _version_used and _version_used < _next_supported_version_tuple:
+ warnings.warn(
+ f"Package {_package_label} depends on "
+ + f"{_dependency_package}, currently installed at version "
+ + f"{_version_used_string}. Future updates to "
+ + f"{_package_label} will require {_dependency_package} at "
+ + f"version {_next_supported_version} or higher{_recommendation}."
+ + " Please ensure "
+ + "that either (a) your Python environment doesn't pin the "
+ + f"version of {_dependency_package}, so that updates to "
+ + f"{_package_label} can require the higher version, or "
+ + "(b) you manually update your Python environment to use at "
+ + f"least version {_next_supported_version} of "
+ + f"{_dependency_package}.",
+ FutureWarning,
+ )
+ except Exception:
+ warnings.warn(
+ "Could not determine the version of Python "
+ + "currently being used. To continue receiving "
+ + "updates for {_package_label}, ensure you are "
+ + "using a supported version of Python; see "
+ + "https://devguide.python.org/versions/"
+ )
__all__ = (
"BigtableAsyncClient",
+ "ArrayValue",
"BigtableClient",
"Cell",
"CheckAndMutateRowRequest",
"CheckAndMutateRowResponse",
"Column",
+ "ColumnMetadata",
"ColumnRange",
+ "ExecuteQueryRequest",
+ "ExecuteQueryResponse",
"Family",
+ "FeatureFlags",
+ "FullReadStatsView",
+ "GenerateInitialChangeStreamPartitionsRequest",
+ "GenerateInitialChangeStreamPartitionsResponse",
+ "Idempotency",
"MutateRowRequest",
"MutateRowResponse",
"MutateRowsRequest",
"MutateRowsResponse",
"Mutation",
+ "PartialResultSet",
+ "PeerInfo",
"PingAndWarmRequest",
"PingAndWarmResponse",
+ "PrepareQueryRequest",
+ "PrepareQueryResponse",
+ "ProtoFormat",
+ "ProtoRows",
+ "ProtoRowsBatch",
+ "ProtoSchema",
+ "RateLimitInfo",
+ "ReadChangeStreamRequest",
+ "ReadChangeStreamResponse",
+ "ReadIterationStats",
"ReadModifyWriteRowRequest",
"ReadModifyWriteRowResponse",
"ReadModifyWriteRule",
"ReadRowsRequest",
"ReadRowsResponse",
+ "RequestLatencyStats",
+ "RequestStats",
+ "ResponseParams",
+ "ResultSetMetadata",
"Row",
"RowFilter",
"RowRange",
"RowSet",
"SampleRowKeysRequest",
"SampleRowKeysResponse",
+ "StreamContinuationToken",
+ "StreamContinuationTokens",
+ "StreamPartition",
"TimestampRange",
+ "Type",
+ "Value",
"ValueRange",
)
diff --git a/google/cloud/bigtable_v2/gapic_metadata.json b/google/cloud/bigtable_v2/gapic_metadata.json
index 4ceadc151..83504fbc1 100644
--- a/google/cloud/bigtable_v2/gapic_metadata.json
+++ b/google/cloud/bigtable_v2/gapic_metadata.json
@@ -15,6 +15,16 @@
"check_and_mutate_row"
]
},
+ "ExecuteQuery": {
+ "methods": [
+ "execute_query"
+ ]
+ },
+ "GenerateInitialChangeStreamPartitions": {
+ "methods": [
+ "generate_initial_change_stream_partitions"
+ ]
+ },
"MutateRow": {
"methods": [
"mutate_row"
@@ -30,6 +40,16 @@
"ping_and_warm"
]
},
+ "PrepareQuery": {
+ "methods": [
+ "prepare_query"
+ ]
+ },
+ "ReadChangeStream": {
+ "methods": [
+ "read_change_stream"
+ ]
+ },
"ReadModifyWriteRow": {
"methods": [
"read_modify_write_row"
@@ -55,6 +75,16 @@
"check_and_mutate_row"
]
},
+ "ExecuteQuery": {
+ "methods": [
+ "execute_query"
+ ]
+ },
+ "GenerateInitialChangeStreamPartitions": {
+ "methods": [
+ "generate_initial_change_stream_partitions"
+ ]
+ },
"MutateRow": {
"methods": [
"mutate_row"
@@ -70,6 +100,76 @@
"ping_and_warm"
]
},
+ "PrepareQuery": {
+ "methods": [
+ "prepare_query"
+ ]
+ },
+ "ReadChangeStream": {
+ "methods": [
+ "read_change_stream"
+ ]
+ },
+ "ReadModifyWriteRow": {
+ "methods": [
+ "read_modify_write_row"
+ ]
+ },
+ "ReadRows": {
+ "methods": [
+ "read_rows"
+ ]
+ },
+ "SampleRowKeys": {
+ "methods": [
+ "sample_row_keys"
+ ]
+ }
+ }
+ },
+ "rest": {
+ "libraryClient": "BigtableClient",
+ "rpcs": {
+ "CheckAndMutateRow": {
+ "methods": [
+ "check_and_mutate_row"
+ ]
+ },
+ "ExecuteQuery": {
+ "methods": [
+ "execute_query"
+ ]
+ },
+ "GenerateInitialChangeStreamPartitions": {
+ "methods": [
+ "generate_initial_change_stream_partitions"
+ ]
+ },
+ "MutateRow": {
+ "methods": [
+ "mutate_row"
+ ]
+ },
+ "MutateRows": {
+ "methods": [
+ "mutate_rows"
+ ]
+ },
+ "PingAndWarm": {
+ "methods": [
+ "ping_and_warm"
+ ]
+ },
+ "PrepareQuery": {
+ "methods": [
+ "prepare_query"
+ ]
+ },
+ "ReadChangeStream": {
+ "methods": [
+ "read_change_stream"
+ ]
+ },
"ReadModifyWriteRow": {
"methods": [
"read_modify_write_row"
diff --git a/google/cloud/bigtable_v2/gapic_version.py b/google/cloud/bigtable_v2/gapic_version.py
new file mode 100644
index 000000000..6d72a226d
--- /dev/null
+++ b/google/cloud/bigtable_v2/gapic_version.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+# Copyright 2025 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.
+#
+__version__ = "2.35.0" # {x-release-please-version}
diff --git a/google/cloud/bigtable_v2/services/__init__.py b/google/cloud/bigtable_v2/services/__init__.py
index e8e1c3845..cbf94b283 100644
--- a/google/cloud/bigtable_v2/services/__init__.py
+++ b/google/cloud/bigtable_v2/services/__init__.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/google/cloud/bigtable_v2/services/bigtable/__init__.py b/google/cloud/bigtable_v2/services/bigtable/__init__.py
index cfce7b6b8..c74141156 100644
--- a/google/cloud/bigtable_v2/services/bigtable/__init__.py
+++ b/google/cloud/bigtable_v2/services/bigtable/__init__.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/google/cloud/bigtable_v2/services/bigtable/async_client.py b/google/cloud/bigtable_v2/services/bigtable/async_client.py
index c5f673a74..0a9442287 100644
--- a/google/cloud/bigtable_v2/services/bigtable/async_client.py
+++ b/google/cloud/bigtable_v2/services/bigtable/async_client.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -13,12 +13,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+import logging as std_logging
from collections import OrderedDict
-import functools
import re
from typing import (
Dict,
+ Callable,
Mapping,
+ MutableMapping,
+ MutableSequence,
Optional,
AsyncIterable,
Awaitable,
@@ -27,26 +30,40 @@
Type,
Union,
)
-import pkg_resources
+
+from google.cloud.bigtable_v2 import gapic_version as package_version
from google.api_core.client_options import ClientOptions
from google.api_core import exceptions as core_exceptions
from google.api_core import gapic_v1
-from google.api_core import retry as retries
+from google.api_core import retry_async as retries
from google.auth import credentials as ga_credentials # type: ignore
from google.oauth2 import service_account # type: ignore
+import google.protobuf
+
try:
- OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault]
+ OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None]
except AttributeError: # pragma: NO COVER
- OptionalRetry = Union[retries.Retry, object] # type: ignore
+ OptionalRetry = Union[retries.AsyncRetry, object, None] # type: ignore
from google.cloud.bigtable_v2.types import bigtable
from google.cloud.bigtable_v2.types import data
+from google.cloud.bigtable_v2.types import request_stats
+from google.protobuf import timestamp_pb2 # type: ignore
from .transports.base import BigtableTransport, DEFAULT_CLIENT_INFO
from .transports.grpc_asyncio import BigtableGrpcAsyncIOTransport
from .client import BigtableClient
+try:
+ from google.api_core import client_logging # type: ignore
+
+ CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER
+except ImportError: # pragma: NO COVER
+ CLIENT_LOGGING_SUPPORTED = False
+
+_LOGGER = std_logging.getLogger(__name__)
+
class BigtableAsyncClient:
"""Service for reading from and writing to existing Bigtable
@@ -55,11 +72,21 @@ class BigtableAsyncClient:
_client: BigtableClient
+ # Copy defaults from the synchronous client for use here.
+ # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead.
DEFAULT_ENDPOINT = BigtableClient.DEFAULT_ENDPOINT
DEFAULT_MTLS_ENDPOINT = BigtableClient.DEFAULT_MTLS_ENDPOINT
+ _DEFAULT_ENDPOINT_TEMPLATE = BigtableClient._DEFAULT_ENDPOINT_TEMPLATE
+ _DEFAULT_UNIVERSE = BigtableClient._DEFAULT_UNIVERSE
+ authorized_view_path = staticmethod(BigtableClient.authorized_view_path)
+ parse_authorized_view_path = staticmethod(BigtableClient.parse_authorized_view_path)
instance_path = staticmethod(BigtableClient.instance_path)
parse_instance_path = staticmethod(BigtableClient.parse_instance_path)
+ materialized_view_path = staticmethod(BigtableClient.materialized_view_path)
+ parse_materialized_view_path = staticmethod(
+ BigtableClient.parse_materialized_view_path
+ )
table_path = staticmethod(BigtableClient.table_path)
parse_table_path = staticmethod(BigtableClient.parse_table_path)
common_billing_account_path = staticmethod(
@@ -128,7 +155,7 @@ def get_mtls_endpoint_and_cert_source(
The API endpoint is determined in the following order:
(1) if `client_options.api_endpoint` if provided, use the provided one.
(2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the
- default mTLS endpoint; if the environment variabel is "never", use the default API
+ default mTLS endpoint; if the environment variable is "never", use the default API
endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise
use the default API endpoint.
@@ -157,19 +184,38 @@ def transport(self) -> BigtableTransport:
"""
return self._client.transport
- get_transport_class = functools.partial(
- type(BigtableClient).get_transport_class, type(BigtableClient)
- )
+ @property
+ def api_endpoint(self):
+ """Return the API endpoint used by the client instance.
+
+ Returns:
+ str: The API endpoint used by the client instance.
+ """
+ return self._client._api_endpoint
+
+ @property
+ def universe_domain(self) -> str:
+ """Return the universe domain used by the client instance.
+
+ Returns:
+ str: The universe domain used
+ by the client instance.
+ """
+ return self._client._universe_domain
+
+ get_transport_class = BigtableClient.get_transport_class
def __init__(
self,
*,
- credentials: ga_credentials.Credentials = None,
- transport: Union[str, BigtableTransport] = "grpc_asyncio",
- client_options: ClientOptions = None,
+ credentials: Optional[ga_credentials.Credentials] = None,
+ transport: Optional[
+ Union[str, BigtableTransport, Callable[..., BigtableTransport]]
+ ] = "grpc_asyncio",
+ client_options: Optional[ClientOptions] = None,
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
- """Instantiates the bigtable client.
+ """Instantiates the bigtable async client.
Args:
credentials (Optional[google.auth.credentials.Credentials]): The
@@ -177,26 +223,43 @@ def __init__(
credentials identify the application to the service; if none
are specified, the client will attempt to ascertain the
credentials from the environment.
- transport (Union[str, ~.BigtableTransport]): The
- transport to use. If set to None, a transport is chosen
- automatically.
- client_options (ClientOptions): Custom options for the client. It
- won't take effect if a ``transport`` instance is provided.
- (1) The ``api_endpoint`` property can be used to override the
- default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
- environment variable can also be used to override the endpoint:
+ transport (Optional[Union[str,BigtableTransport,Callable[..., BigtableTransport]]]):
+ The transport to use, or a Callable that constructs and returns a new transport to use.
+ If a Callable is given, it will be called with the same set of initialization
+ arguments as used in the BigtableTransport constructor.
+ If set to None, a transport is chosen automatically.
+ client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]):
+ Custom options for the client.
+
+ 1. The ``api_endpoint`` property can be used to override the
+ default endpoint provided by the client when ``transport`` is
+ not explicitly provided. Only if this property is not set and
+ ``transport`` was not explicitly provided, the endpoint is
+ determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment
+ variable, which have one of the following values:
"always" (always use the default mTLS endpoint), "never" (always
- use the default regular endpoint) and "auto" (auto switch to the
- default mTLS endpoint if client certificate is present, this is
- the default value). However, the ``api_endpoint`` property takes
- precedence if provided.
- (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ use the default regular endpoint) and "auto" (auto-switch to the
+ default mTLS endpoint if client certificate is present; this is
+ the default value).
+
+ 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
is "true", then the ``client_cert_source`` property can be used
- to provide client certificate for mutual TLS transport. If
+ to provide a client certificate for mTLS transport. If
not provided, the default SSL client certificate will be used if
present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
set, no client certificate will be used.
+ 3. The ``universe_domain`` property can be used to override the
+ default "googleapis.com" universe. Note that ``api_endpoint``
+ property still takes precedence; and ``universe_domain`` is
+ currently not supported for mTLS.
+
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
+ your own client library.
+
Raises:
google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
creation failed for any reason.
@@ -208,15 +271,37 @@ def __init__(
client_info=client_info,
)
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ std_logging.DEBUG
+ ): # pragma: NO COVER
+ _LOGGER.debug(
+ "Created client `google.bigtable_v2.BigtableAsyncClient`.",
+ extra={
+ "serviceName": "google.bigtable.v2.Bigtable",
+ "universeDomain": getattr(
+ self._client._transport._credentials, "universe_domain", ""
+ ),
+ "credentialsType": f"{type(self._client._transport._credentials).__module__}.{type(self._client._transport._credentials).__qualname__}",
+ "credentialsInfo": getattr(
+ self.transport._credentials, "get_cred_info", lambda: None
+ )(),
+ }
+ if hasattr(self._client._transport, "_credentials")
+ else {
+ "serviceName": "google.bigtable.v2.Bigtable",
+ "credentialsType": None,
+ },
+ )
+
def read_rows(
self,
- request: Union[bigtable.ReadRowsRequest, dict] = None,
+ request: Optional[Union[bigtable.ReadRowsRequest, dict]] = None,
*,
- table_name: str = None,
- app_profile_id: str = None,
+ table_name: Optional[str] = None,
+ app_profile_id: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> Awaitable[AsyncIterable[bigtable.ReadRowsResponse]]:
r"""Streams back the contents of all requested rows in
key order, optionally applying the same Reader filter to
@@ -226,12 +311,14 @@ def read_rows(
ReadRowsResponse documentation for details.
Args:
- request (Union[google.cloud.bigtable_v2.types.ReadRowsRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_v2.types.ReadRowsRequest, dict]]):
The request object. Request message for
Bigtable.ReadRows.
table_name (:class:`str`):
- Required. The unique name of the table from which to
- read. Values are of the form
+ Optional. The unique name of the table from which to
+ read.
+
+ Values are of the form
``projects//instances//tables/``.
This corresponds to the ``table_name`` field
@@ -246,11 +333,13 @@ def read_rows(
This corresponds to the ``app_profile_id`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
AsyncIterable[google.cloud.bigtable_v2.types.ReadRowsResponse]:
@@ -259,16 +348,22 @@ def read_rows(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([table_name, app_profile_id])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [table_name, app_profile_id]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable.ReadRowsRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable.ReadRowsRequest):
+ request = bigtable.ReadRowsRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
@@ -279,19 +374,43 @@ def read_rows(
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.read_rows,
- default_timeout=43200.0,
- client_info=DEFAULT_CLIENT_INFO,
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.read_rows
+ ]
+
+ header_params = {}
+
+ routing_param_regex = re.compile(
+ "^(?Pprojects/[^/]+/instances/[^/]+/tables/[^/]+)$"
)
+ regex_match = routing_param_regex.match(request.table_name)
+ if regex_match and regex_match.group("table_name"):
+ header_params["table_name"] = regex_match.group("table_name")
- # Certain fields should be provided within the metadata header;
- # add these here.
- metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata(
- (("table_name", request.table_name),)
- ),
+ if True: # always attach app_profile_id, even if empty string
+ header_params["app_profile_id"] = request.app_profile_id
+
+ routing_param_regex = re.compile(
+ "^(?Pprojects/[^/]+/instances/[^/]+/tables/[^/]+)(?:/.*)?$"
)
+ regex_match = routing_param_regex.match(request.authorized_view_name)
+ if regex_match and regex_match.group("table_name"):
+ header_params["table_name"] = regex_match.group("table_name")
+
+ routing_param_regex = re.compile(
+ "^(?Pprojects/[^/]+/instances/[^/]+)(?:/.*)?$"
+ )
+ regex_match = routing_param_regex.match(request.materialized_view_name)
+ if regex_match and regex_match.group("name"):
+ header_params["name"] = regex_match.group("name")
+
+ if header_params:
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata(header_params),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
# Send the request.
response = rpc(
@@ -306,13 +425,13 @@ def read_rows(
def sample_row_keys(
self,
- request: Union[bigtable.SampleRowKeysRequest, dict] = None,
+ request: Optional[Union[bigtable.SampleRowKeysRequest, dict]] = None,
*,
- table_name: str = None,
- app_profile_id: str = None,
+ table_name: Optional[str] = None,
+ app_profile_id: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> Awaitable[AsyncIterable[bigtable.SampleRowKeysResponse]]:
r"""Returns a sample of row keys in the table. The
returned row keys will delimit contiguous sections of
@@ -321,12 +440,14 @@ def sample_row_keys(
mapreduces.
Args:
- request (Union[google.cloud.bigtable_v2.types.SampleRowKeysRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_v2.types.SampleRowKeysRequest, dict]]):
The request object. Request message for
Bigtable.SampleRowKeys.
table_name (:class:`str`):
- Required. The unique name of the table from which to
- sample row keys. Values are of the form
+ Optional. The unique name of the table from which to
+ sample row keys.
+
+ Values are of the form
``projects//instances//tables/``.
This corresponds to the ``table_name`` field
@@ -341,11 +462,13 @@ def sample_row_keys(
This corresponds to the ``app_profile_id`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
AsyncIterable[google.cloud.bigtable_v2.types.SampleRowKeysResponse]:
@@ -354,16 +477,22 @@ def sample_row_keys(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([table_name, app_profile_id])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [table_name, app_profile_id]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable.SampleRowKeysRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable.SampleRowKeysRequest):
+ request = bigtable.SampleRowKeysRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
@@ -374,19 +503,43 @@ def sample_row_keys(
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.sample_row_keys,
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.sample_row_keys
+ ]
+
+ header_params = {}
+
+ routing_param_regex = re.compile(
+ "^(?Pprojects/[^/]+/instances/[^/]+/tables/[^/]+)$"
)
+ regex_match = routing_param_regex.match(request.table_name)
+ if regex_match and regex_match.group("table_name"):
+ header_params["table_name"] = regex_match.group("table_name")
- # Certain fields should be provided within the metadata header;
- # add these here.
- metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata(
- (("table_name", request.table_name),)
- ),
+ if True: # always attach app_profile_id, even if empty string
+ header_params["app_profile_id"] = request.app_profile_id
+
+ routing_param_regex = re.compile(
+ "^(?Pprojects/[^/]+/instances/[^/]+/tables/[^/]+)(?:/.*)?$"
)
+ regex_match = routing_param_regex.match(request.authorized_view_name)
+ if regex_match and regex_match.group("table_name"):
+ header_params["table_name"] = regex_match.group("table_name")
+
+ routing_param_regex = re.compile(
+ "^(?Pprojects/[^/]+/instances/[^/]+)(?:/.*)?$"
+ )
+ regex_match = routing_param_regex.match(request.materialized_view_name)
+ if regex_match and regex_match.group("name"):
+ header_params["name"] = regex_match.group("name")
+
+ if header_params:
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata(header_params),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
# Send the request.
response = rpc(
@@ -401,26 +554,28 @@ def sample_row_keys(
async def mutate_row(
self,
- request: Union[bigtable.MutateRowRequest, dict] = None,
+ request: Optional[Union[bigtable.MutateRowRequest, dict]] = None,
*,
- table_name: str = None,
- row_key: bytes = None,
- mutations: Sequence[data.Mutation] = None,
- app_profile_id: str = None,
+ table_name: Optional[str] = None,
+ row_key: Optional[bytes] = None,
+ mutations: Optional[MutableSequence[data.Mutation]] = None,
+ app_profile_id: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> bigtable.MutateRowResponse:
r"""Mutates a row atomically. Cells already present in the row are
left unchanged unless explicitly changed by ``mutation``.
Args:
- request (Union[google.cloud.bigtable_v2.types.MutateRowRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_v2.types.MutateRowRequest, dict]]):
The request object. Request message for
Bigtable.MutateRow.
table_name (:class:`str`):
- Required. The unique name of the table to which the
- mutation should be applied. Values are of the form
+ Optional. The unique name of the table to which the
+ mutation should be applied.
+
+ Values are of the form
``projects//instances//tables/``.
This corresponds to the ``table_name`` field
@@ -433,7 +588,7 @@ async def mutate_row(
This corresponds to the ``row_key`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- mutations (:class:`Sequence[google.cloud.bigtable_v2.types.Mutation]`):
+ mutations (:class:`MutableSequence[google.cloud.bigtable_v2.types.Mutation]`):
Required. Changes to be atomically
applied to the specified row. Entries
are applied in order, meaning that
@@ -453,11 +608,13 @@ async def mutate_row(
This corresponds to the ``app_profile_id`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_v2.types.MutateRowResponse:
@@ -466,16 +623,22 @@ async def mutate_row(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([table_name, row_key, mutations, app_profile_id])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [table_name, row_key, mutations, app_profile_id]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable.MutateRowRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable.MutateRowRequest):
+ request = bigtable.MutateRowRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
@@ -490,29 +653,36 @@ async def mutate_row(
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.mutate_row,
- default_retry=retries.Retry(
- initial=0.01,
- maximum=60.0,
- multiplier=2,
- predicate=retries.if_exception_type(
- core_exceptions.DeadlineExceeded,
- core_exceptions.ServiceUnavailable,
- ),
- deadline=60.0,
- ),
- default_timeout=60.0,
- client_info=DEFAULT_CLIENT_INFO,
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.mutate_row
+ ]
+
+ header_params = {}
+
+ routing_param_regex = re.compile(
+ "^(?Pprojects/[^/]+/instances/[^/]+/tables/[^/]+)$"
)
+ regex_match = routing_param_regex.match(request.table_name)
+ if regex_match and regex_match.group("table_name"):
+ header_params["table_name"] = regex_match.group("table_name")
- # Certain fields should be provided within the metadata header;
- # add these here.
- metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata(
- (("table_name", request.table_name),)
- ),
+ if True: # always attach app_profile_id, even if empty string
+ header_params["app_profile_id"] = request.app_profile_id
+
+ routing_param_regex = re.compile(
+ "^(?Pprojects/[^/]+/instances/[^/]+/tables/[^/]+)(?:/.*)?$"
)
+ regex_match = routing_param_regex.match(request.authorized_view_name)
+ if regex_match and regex_match.group("table_name"):
+ header_params["table_name"] = regex_match.group("table_name")
+
+ if header_params:
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata(header_params),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
# Send the request.
response = await rpc(
@@ -527,32 +697,34 @@ async def mutate_row(
def mutate_rows(
self,
- request: Union[bigtable.MutateRowsRequest, dict] = None,
+ request: Optional[Union[bigtable.MutateRowsRequest, dict]] = None,
*,
- table_name: str = None,
- entries: Sequence[bigtable.MutateRowsRequest.Entry] = None,
- app_profile_id: str = None,
+ table_name: Optional[str] = None,
+ entries: Optional[MutableSequence[bigtable.MutateRowsRequest.Entry]] = None,
+ app_profile_id: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> Awaitable[AsyncIterable[bigtable.MutateRowsResponse]]:
r"""Mutates multiple rows in a batch. Each individual row
is mutated atomically as in MutateRow, but the entire
batch is not executed atomically.
Args:
- request (Union[google.cloud.bigtable_v2.types.MutateRowsRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_v2.types.MutateRowsRequest, dict]]):
The request object. Request message for
BigtableService.MutateRows.
table_name (:class:`str`):
- Required. The unique name of the
- table to which the mutations should be
- applied.
+ Optional. The unique name of the table to which the
+ mutations should be applied.
+
+ Values are of the form
+ ``projects//instances//tables/``.
This corresponds to the ``table_name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- entries (:class:`Sequence[google.cloud.bigtable_v2.types.MutateRowsRequest.Entry]`):
+ entries (:class:`MutableSequence[google.cloud.bigtable_v2.types.MutateRowsRequest.Entry]`):
Required. The row keys and
corresponding mutations to be applied in
bulk. Each entry is applied as an atomic
@@ -575,11 +747,13 @@ def mutate_rows(
This corresponds to the ``app_profile_id`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
AsyncIterable[google.cloud.bigtable_v2.types.MutateRowsResponse]:
@@ -588,16 +762,22 @@ def mutate_rows(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([table_name, entries, app_profile_id])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [table_name, entries, app_profile_id]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable.MutateRowsRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable.MutateRowsRequest):
+ request = bigtable.MutateRowsRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
@@ -610,19 +790,36 @@ def mutate_rows(
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.mutate_rows,
- default_timeout=600.0,
- client_info=DEFAULT_CLIENT_INFO,
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.mutate_rows
+ ]
+
+ header_params = {}
+
+ routing_param_regex = re.compile(
+ "^(?Pprojects/[^/]+/instances/[^/]+/tables/[^/]+)$"
)
+ regex_match = routing_param_regex.match(request.table_name)
+ if regex_match and regex_match.group("table_name"):
+ header_params["table_name"] = regex_match.group("table_name")
- # Certain fields should be provided within the metadata header;
- # add these here.
- metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata(
- (("table_name", request.table_name),)
- ),
+ if True: # always attach app_profile_id, even if empty string
+ header_params["app_profile_id"] = request.app_profile_id
+
+ routing_param_regex = re.compile(
+ "^(?Pprojects/[^/]+/instances/[^/]+/tables/[^/]+)(?:/.*)?$"
)
+ regex_match = routing_param_regex.match(request.authorized_view_name)
+ if regex_match and regex_match.group("table_name"):
+ header_params["table_name"] = regex_match.group("table_name")
+
+ if header_params:
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata(header_params),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
# Send the request.
response = rpc(
@@ -637,29 +834,30 @@ def mutate_rows(
async def check_and_mutate_row(
self,
- request: Union[bigtable.CheckAndMutateRowRequest, dict] = None,
+ request: Optional[Union[bigtable.CheckAndMutateRowRequest, dict]] = None,
*,
- table_name: str = None,
- row_key: bytes = None,
- predicate_filter: data.RowFilter = None,
- true_mutations: Sequence[data.Mutation] = None,
- false_mutations: Sequence[data.Mutation] = None,
- app_profile_id: str = None,
+ table_name: Optional[str] = None,
+ row_key: Optional[bytes] = None,
+ predicate_filter: Optional[data.RowFilter] = None,
+ true_mutations: Optional[MutableSequence[data.Mutation]] = None,
+ false_mutations: Optional[MutableSequence[data.Mutation]] = None,
+ app_profile_id: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> bigtable.CheckAndMutateRowResponse:
r"""Mutates a row atomically based on the output of a
predicate Reader filter.
Args:
- request (Union[google.cloud.bigtable_v2.types.CheckAndMutateRowRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_v2.types.CheckAndMutateRowRequest, dict]]):
The request object. Request message for
Bigtable.CheckAndMutateRow.
table_name (:class:`str`):
- Required. The unique name of the table to which the
- conditional mutation should be applied. Values are of
- the form
+ Optional. The unique name of the table to which the
+ conditional mutation should be applied.
+
+ Values are of the form
``projects//instances//tables/``.
This corresponds to the ``table_name`` field
@@ -683,7 +881,7 @@ async def check_and_mutate_row(
This corresponds to the ``predicate_filter`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- true_mutations (:class:`Sequence[google.cloud.bigtable_v2.types.Mutation]`):
+ true_mutations (:class:`MutableSequence[google.cloud.bigtable_v2.types.Mutation]`):
Changes to be atomically applied to the specified row if
``predicate_filter`` yields at least one cell when
applied to ``row_key``. Entries are applied in order,
@@ -694,7 +892,7 @@ async def check_and_mutate_row(
This corresponds to the ``true_mutations`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- false_mutations (:class:`Sequence[google.cloud.bigtable_v2.types.Mutation]`):
+ false_mutations (:class:`MutableSequence[google.cloud.bigtable_v2.types.Mutation]`):
Changes to be atomically applied to the specified row if
``predicate_filter`` does not yield any cells when
applied to ``row_key``. Entries are applied in order,
@@ -714,11 +912,13 @@ async def check_and_mutate_row(
This corresponds to the ``app_profile_id`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_v2.types.CheckAndMutateRowResponse:
@@ -727,17 +927,18 @@ async def check_and_mutate_row(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any(
- [
- table_name,
- row_key,
- predicate_filter,
- true_mutations,
- false_mutations,
- app_profile_id,
- ]
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [
+ table_name,
+ row_key,
+ predicate_filter,
+ true_mutations,
+ false_mutations,
+ app_profile_id,
+ ]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
)
if request is not None and has_flattened_params:
raise ValueError(
@@ -745,7 +946,10 @@ async def check_and_mutate_row(
"the individual field arguments should be set."
)
- request = bigtable.CheckAndMutateRowRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable.CheckAndMutateRowRequest):
+ request = bigtable.CheckAndMutateRowRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
@@ -764,19 +968,36 @@ async def check_and_mutate_row(
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.check_and_mutate_row,
- default_timeout=20.0,
- client_info=DEFAULT_CLIENT_INFO,
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.check_and_mutate_row
+ ]
+
+ header_params = {}
+
+ routing_param_regex = re.compile(
+ "^(?Pprojects/[^/]+/instances/[^/]+/tables/[^/]+)$"
)
+ regex_match = routing_param_regex.match(request.table_name)
+ if regex_match and regex_match.group("table_name"):
+ header_params["table_name"] = regex_match.group("table_name")
- # Certain fields should be provided within the metadata header;
- # add these here.
- metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata(
- (("table_name", request.table_name),)
- ),
+ if True: # always attach app_profile_id, even if empty string
+ header_params["app_profile_id"] = request.app_profile_id
+
+ routing_param_regex = re.compile(
+ "^(?Pprojects/[^/]+/instances/[^/]+/tables/[^/]+)(?:/.*)?$"
)
+ regex_match = routing_param_regex.match(request.authorized_view_name)
+ if regex_match and regex_match.group("table_name"):
+ header_params["table_name"] = regex_match.group("table_name")
+
+ if header_params:
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata(header_params),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
# Send the request.
response = await rpc(
@@ -791,22 +1012,22 @@ async def check_and_mutate_row(
async def ping_and_warm(
self,
- request: Union[bigtable.PingAndWarmRequest, dict] = None,
+ request: Optional[Union[bigtable.PingAndWarmRequest, dict]] = None,
*,
- name: str = None,
- app_profile_id: str = None,
+ name: Optional[str] = None,
+ app_profile_id: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> bigtable.PingAndWarmResponse:
r"""Warm up associated instance metadata for this
connection. This call is not required but may be useful
for connection keep-alive.
Args:
- request (Union[google.cloud.bigtable_v2.types.PingAndWarmRequest, dict]):
- The request object. Request message for client
- connection keep-alive and warming.
+ request (Optional[Union[google.cloud.bigtable_v2.types.PingAndWarmRequest, dict]]):
+ The request object. Request message for client connection
+ keep-alive and warming.
name (:class:`str`):
Required. The unique name of the instance to check
permissions for as well as respond. Values are of the
@@ -824,11 +1045,13 @@ async def ping_and_warm(
This corresponds to the ``app_profile_id`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_v2.types.PingAndWarmResponse:
@@ -838,16 +1061,22 @@ async def ping_and_warm(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name, app_profile_id])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name, app_profile_id]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable.PingAndWarmRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable.PingAndWarmRequest):
+ request = bigtable.PingAndWarmRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
@@ -858,17 +1087,27 @@ async def ping_and_warm(
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.ping_and_warm,
- default_timeout=None,
- client_info=DEFAULT_CLIENT_INFO,
- )
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.ping_and_warm
+ ]
- # Certain fields should be provided within the metadata header;
- # add these here.
- metadata = tuple(metadata) + (
- gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)),
- )
+ header_params = {}
+
+ routing_param_regex = re.compile("^(?Pprojects/[^/]+/instances/[^/]+)$")
+ regex_match = routing_param_regex.match(request.name)
+ if regex_match and regex_match.group("name"):
+ header_params["name"] = regex_match.group("name")
+
+ if True: # always attach app_profile_id, even if empty string
+ header_params["app_profile_id"] = request.app_profile_id
+
+ if header_params:
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata(header_params),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
# Send the request.
response = await rpc(
@@ -883,15 +1122,15 @@ async def ping_and_warm(
async def read_modify_write_row(
self,
- request: Union[bigtable.ReadModifyWriteRowRequest, dict] = None,
+ request: Optional[Union[bigtable.ReadModifyWriteRowRequest, dict]] = None,
*,
- table_name: str = None,
- row_key: bytes = None,
- rules: Sequence[data.ReadModifyWriteRule] = None,
- app_profile_id: str = None,
+ table_name: Optional[str] = None,
+ row_key: Optional[bytes] = None,
+ rules: Optional[MutableSequence[data.ReadModifyWriteRule]] = None,
+ app_profile_id: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> bigtable.ReadModifyWriteRowResponse:
r"""Modifies a row atomically on the server. The method
reads the latest existing timestamp and value from the
@@ -902,13 +1141,14 @@ async def read_modify_write_row(
contents of all modified cells.
Args:
- request (Union[google.cloud.bigtable_v2.types.ReadModifyWriteRowRequest, dict]):
+ request (Optional[Union[google.cloud.bigtable_v2.types.ReadModifyWriteRowRequest, dict]]):
The request object. Request message for
Bigtable.ReadModifyWriteRow.
table_name (:class:`str`):
- Required. The unique name of the table to which the
- read/modify/write rules should be applied. Values are of
- the form
+ Optional. The unique name of the table to which the
+ read/modify/write rules should be applied.
+
+ Values are of the form
``projects//instances//tables/``.
This corresponds to the ``table_name`` field
@@ -922,13 +1162,15 @@ async def read_modify_write_row(
This corresponds to the ``row_key`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- rules (:class:`Sequence[google.cloud.bigtable_v2.types.ReadModifyWriteRule]`):
+ rules (:class:`MutableSequence[google.cloud.bigtable_v2.types.ReadModifyWriteRule]`):
Required. Rules specifying how the
specified row's contents are to be
transformed into writes. Entries are
applied in order, meaning that earlier
rules will affect the results of later
- ones.
+ ones. At least one entry must be
+ specified, and there can be at most
+ 100000 rules.
This corresponds to the ``rules`` field
on the ``request`` instance; if ``request`` is provided, this
@@ -942,11 +1184,13 @@ async def read_modify_write_row(
This corresponds to the ``app_profile_id`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_v2.types.ReadModifyWriteRowResponse:
@@ -955,16 +1199,22 @@ async def read_modify_write_row(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([table_name, row_key, rules, app_profile_id])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [table_name, row_key, rules, app_profile_id]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- request = bigtable.ReadModifyWriteRowRequest(request)
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable.ReadModifyWriteRowRequest):
+ request = bigtable.ReadModifyWriteRowRequest(request)
# If we have keyword arguments corresponding to fields on the
# request, apply these.
@@ -979,11 +1229,141 @@ async def read_modify_write_row(
# Wrap the RPC method; this adds retry and timeout information,
# and friendly error handling.
- rpc = gapic_v1.method_async.wrap_method(
- self._client._transport.read_modify_write_row,
- default_timeout=20.0,
- client_info=DEFAULT_CLIENT_INFO,
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.read_modify_write_row
+ ]
+
+ header_params = {}
+
+ routing_param_regex = re.compile(
+ "^(?Pprojects/[^/]+/instances/[^/]+/tables/[^/]+)$"
+ )
+ regex_match = routing_param_regex.match(request.table_name)
+ if regex_match and regex_match.group("table_name"):
+ header_params["table_name"] = regex_match.group("table_name")
+
+ if True: # always attach app_profile_id, even if empty string
+ header_params["app_profile_id"] = request.app_profile_id
+
+ routing_param_regex = re.compile(
+ "^(?Pprojects/[^/]+/instances/[^/]+/tables/[^/]+)(?:/.*)?$"
)
+ regex_match = routing_param_regex.match(request.authorized_view_name)
+ if regex_match and regex_match.group("table_name"):
+ header_params["table_name"] = regex_match.group("table_name")
+
+ if header_params:
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata(header_params),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
+ # Send the request.
+ response = await rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def generate_initial_change_stream_partitions(
+ self,
+ request: Optional[
+ Union[bigtable.GenerateInitialChangeStreamPartitionsRequest, dict]
+ ] = None,
+ *,
+ table_name: Optional[str] = None,
+ app_profile_id: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> Awaitable[
+ AsyncIterable[bigtable.GenerateInitialChangeStreamPartitionsResponse]
+ ]:
+ r"""Returns the current list of partitions that make up the table's
+ change stream. The union of partitions will cover the entire
+ keyspace. Partitions can be read with ``ReadChangeStream``.
+ NOTE: This API is only intended to be used by Apache Beam
+ BigtableIO.
+
+ Args:
+ request (Optional[Union[google.cloud.bigtable_v2.types.GenerateInitialChangeStreamPartitionsRequest, dict]]):
+ The request object. NOTE: This API is intended to be used
+ by Apache Beam BigtableIO. Request
+ message for
+ Bigtable.GenerateInitialChangeStreamPartitions.
+ table_name (:class:`str`):
+ Required. The unique name of the table from which to get
+ change stream partitions. Values are of the form
+ ``projects//instances//tables/``.
+ Change streaming must be enabled on the table.
+
+ This corresponds to the ``table_name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ app_profile_id (:class:`str`):
+ This value specifies routing for
+ replication. If not specified, the
+ "default" application profile will be
+ used. Single cluster routing must be
+ configured on the profile.
+
+ This corresponds to the ``app_profile_id`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ AsyncIterable[google.cloud.bigtable_v2.types.GenerateInitialChangeStreamPartitionsResponse]:
+ NOTE: This API is intended to be used
+ by Apache Beam BigtableIO. Response
+ message for
+ Bigtable.GenerateInitialChangeStreamPartitions.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [table_name, app_profile_id]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(
+ request, bigtable.GenerateInitialChangeStreamPartitionsRequest
+ ):
+ request = bigtable.GenerateInitialChangeStreamPartitionsRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if table_name is not None:
+ request.table_name = table_name
+ if app_profile_id is not None:
+ request.app_profile_id = app_profile_id
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.generate_initial_change_stream_partitions
+ ]
# Certain fields should be provided within the metadata header;
# add these here.
@@ -993,6 +1373,235 @@ async def read_modify_write_row(
),
)
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
+ # Send the request.
+ response = rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def read_change_stream(
+ self,
+ request: Optional[Union[bigtable.ReadChangeStreamRequest, dict]] = None,
+ *,
+ table_name: Optional[str] = None,
+ app_profile_id: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> Awaitable[AsyncIterable[bigtable.ReadChangeStreamResponse]]:
+ r"""Reads changes from a table's change stream. Changes
+ will reflect both user-initiated mutations and mutations
+ that are caused by garbage collection.
+ NOTE: This API is only intended to be used by Apache
+ Beam BigtableIO.
+
+ Args:
+ request (Optional[Union[google.cloud.bigtable_v2.types.ReadChangeStreamRequest, dict]]):
+ The request object. NOTE: This API is intended to be used
+ by Apache Beam BigtableIO. Request
+ message for Bigtable.ReadChangeStream.
+ table_name (:class:`str`):
+ Required. The unique name of the table from which to
+ read a change stream. Values are of the form
+ ``projects//instances//tables/``.
+ Change streaming must be enabled on the table.
+
+ This corresponds to the ``table_name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ app_profile_id (:class:`str`):
+ This value specifies routing for
+ replication. If not specified, the
+ "default" application profile will be
+ used. Single cluster routing must be
+ configured on the profile.
+
+ This corresponds to the ``app_profile_id`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ AsyncIterable[google.cloud.bigtable_v2.types.ReadChangeStreamResponse]:
+ NOTE: This API is intended to be used
+ by Apache Beam BigtableIO. Response
+ message for Bigtable.ReadChangeStream.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [table_name, app_profile_id]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable.ReadChangeStreamRequest):
+ request = bigtable.ReadChangeStreamRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if table_name is not None:
+ request.table_name = table_name
+ if app_profile_id is not None:
+ request.app_profile_id = app_profile_id
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.read_change_stream
+ ]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata(
+ (("table_name", request.table_name),)
+ ),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
+ # Send the request.
+ response = rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ async def prepare_query(
+ self,
+ request: Optional[Union[bigtable.PrepareQueryRequest, dict]] = None,
+ *,
+ instance_name: Optional[str] = None,
+ query: Optional[str] = None,
+ app_profile_id: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> bigtable.PrepareQueryResponse:
+ r"""Prepares a GoogleSQL query for execution on a
+ particular Bigtable instance.
+
+ Args:
+ request (Optional[Union[google.cloud.bigtable_v2.types.PrepareQueryRequest, dict]]):
+ The request object. Request message for
+ Bigtable.PrepareQuery
+ instance_name (:class:`str`):
+ Required. The unique name of the instance against which
+ the query should be executed. Values are of the form
+ ``projects//instances/``
+
+ This corresponds to the ``instance_name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ query (:class:`str`):
+ Required. The query string.
+ This corresponds to the ``query`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ app_profile_id (:class:`str`):
+ Optional. This value specifies routing for preparing the
+ query. Note that this ``app_profile_id`` is only used
+ for preparing the query. The actual query execution will
+ use the app profile specified in the
+ ``ExecuteQueryRequest``. If not specified, the
+ ``default`` application profile will be used.
+
+ This corresponds to the ``app_profile_id`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.cloud.bigtable_v2.types.PrepareQueryResponse:
+ Response message for
+ Bigtable.PrepareQueryResponse
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [instance_name, query, app_profile_id]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable.PrepareQueryRequest):
+ request = bigtable.PrepareQueryRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if instance_name is not None:
+ request.instance_name = instance_name
+ if query is not None:
+ request.query = query
+ if app_profile_id is not None:
+ request.app_profile_id = app_profile_id
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.prepare_query
+ ]
+
+ header_params = {}
+
+ routing_param_regex = re.compile("^(?Pprojects/[^/]+/instances/[^/]+)$")
+ regex_match = routing_param_regex.match(request.instance_name)
+ if regex_match and regex_match.group("name"):
+ header_params["name"] = regex_match.group("name")
+
+ if True: # always attach app_profile_id, even if empty string
+ header_params["app_profile_id"] = request.app_profile_id
+
+ if header_params:
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata(header_params),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
# Send the request.
response = await rpc(
request,
@@ -1004,21 +1613,139 @@ async def read_modify_write_row(
# Done; return the response.
return response
- async def __aenter__(self):
+ def execute_query(
+ self,
+ request: Optional[Union[bigtable.ExecuteQueryRequest, dict]] = None,
+ *,
+ instance_name: Optional[str] = None,
+ query: Optional[str] = None,
+ app_profile_id: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> Awaitable[AsyncIterable[bigtable.ExecuteQueryResponse]]:
+ r"""Executes a SQL query against a particular Bigtable
+ instance.
+
+ Args:
+ request (Optional[Union[google.cloud.bigtable_v2.types.ExecuteQueryRequest, dict]]):
+ The request object. Request message for
+ Bigtable.ExecuteQuery
+ instance_name (:class:`str`):
+ Required. The unique name of the instance against which
+ the query should be executed. Values are of the form
+ ``projects//instances/``
+
+ This corresponds to the ``instance_name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ query (:class:`str`):
+ Required. The query string.
+
+ Exactly one of ``query`` and ``prepared_query`` is
+ required. Setting both or neither is an
+ ``INVALID_ARGUMENT``.
+
+ This corresponds to the ``query`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ app_profile_id (:class:`str`):
+ Optional. This value specifies routing for replication.
+ If not specified, the ``default`` application profile
+ will be used.
+
+ This corresponds to the ``app_profile_id`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ AsyncIterable[google.cloud.bigtable_v2.types.ExecuteQueryResponse]:
+ Response message for
+ Bigtable.ExecuteQuery
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [instance_name, query, app_profile_id]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable.ExecuteQueryRequest):
+ request = bigtable.ExecuteQueryRequest(request)
+
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if instance_name is not None:
+ request.instance_name = instance_name
+ if query is not None:
+ request.query = query
+ if app_profile_id is not None:
+ request.app_profile_id = app_profile_id
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._client._transport._wrapped_methods[
+ self._client._transport.execute_query
+ ]
+
+ header_params = {}
+
+ routing_param_regex = re.compile("^(?Pprojects/[^/]+/instances/[^/]+)$")
+ regex_match = routing_param_regex.match(request.instance_name)
+ if regex_match and regex_match.group("name"):
+ header_params["name"] = regex_match.group("name")
+
+ if True: # always attach app_profile_id, even if empty string
+ header_params["app_profile_id"] = request.app_profile_id
+
+ if header_params:
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata(header_params),
+ )
+
+ # Validate the universe domain.
+ self._client._validate_universe_domain()
+
+ # Send the request.
+ response = rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ async def __aenter__(self) -> "BigtableAsyncClient":
return self
async def __aexit__(self, exc_type, exc, tb):
await self.transport.close()
-try:
- DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
- gapic_version=pkg_resources.get_distribution(
- "google-cloud-bigtable",
- ).version,
- )
-except pkg_resources.DistributionNotFound:
- DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
+DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
+ gapic_version=package_version.__version__
+)
+
+if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER
+ DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__
__all__ = ("BigtableAsyncClient",)
diff --git a/google/cloud/bigtable_v2/services/bigtable/client.py b/google/cloud/bigtable_v2/services/bigtable/client.py
index a0dfdff4e..5eb6ba894 100644
--- a/google/cloud/bigtable_v2/services/bigtable/client.py
+++ b/google/cloud/bigtable_v2/services/bigtable/client.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -14,10 +14,28 @@
# limitations under the License.
#
from collections import OrderedDict
+from http import HTTPStatus
+import json
+import logging as std_logging
import os
import re
-from typing import Dict, Mapping, Optional, Iterable, Sequence, Tuple, Type, Union
-import pkg_resources
+from typing import (
+ Dict,
+ Callable,
+ Mapping,
+ MutableMapping,
+ MutableSequence,
+ Optional,
+ Iterable,
+ Sequence,
+ Tuple,
+ Type,
+ Union,
+ cast,
+)
+import warnings
+
+from google.cloud.bigtable_v2 import gapic_version as package_version
from google.api_core import client_options as client_options_lib
from google.api_core import exceptions as core_exceptions
@@ -28,17 +46,30 @@
from google.auth.transport.grpc import SslCredentials # type: ignore
from google.auth.exceptions import MutualTLSChannelError # type: ignore
from google.oauth2 import service_account # type: ignore
+import google.protobuf
try:
- OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault]
+ OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None]
except AttributeError: # pragma: NO COVER
- OptionalRetry = Union[retries.Retry, object] # type: ignore
+ OptionalRetry = Union[retries.Retry, object, None] # type: ignore
+
+try:
+ from google.api_core import client_logging # type: ignore
+
+ CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER
+except ImportError: # pragma: NO COVER
+ CLIENT_LOGGING_SUPPORTED = False
+
+_LOGGER = std_logging.getLogger(__name__)
from google.cloud.bigtable_v2.types import bigtable
from google.cloud.bigtable_v2.types import data
+from google.cloud.bigtable_v2.types import request_stats
+from google.protobuf import timestamp_pb2 # type: ignore
from .transports.base import BigtableTransport, DEFAULT_CLIENT_INFO
from .transports.grpc import BigtableGrpcTransport
from .transports.grpc_asyncio import BigtableGrpcAsyncIOTransport
+from .transports.rest import BigtableRestTransport
class BigtableClientMeta(type):
@@ -52,10 +83,11 @@ class BigtableClientMeta(type):
_transport_registry = OrderedDict() # type: Dict[str, Type[BigtableTransport]]
_transport_registry["grpc"] = BigtableGrpcTransport
_transport_registry["grpc_asyncio"] = BigtableGrpcAsyncIOTransport
+ _transport_registry["rest"] = BigtableRestTransport
def get_transport_class(
cls,
- label: str = None,
+ label: Optional[str] = None,
) -> Type[BigtableTransport]:
"""Returns an appropriate transport class.
@@ -110,11 +142,43 @@ def _get_default_mtls_endpoint(api_endpoint):
return api_endpoint.replace(".googleapis.com", ".mtls.googleapis.com")
+ # Note: DEFAULT_ENDPOINT is deprecated. Use _DEFAULT_ENDPOINT_TEMPLATE instead.
DEFAULT_ENDPOINT = "bigtable.googleapis.com"
DEFAULT_MTLS_ENDPOINT = _get_default_mtls_endpoint.__func__( # type: ignore
DEFAULT_ENDPOINT
)
+ _DEFAULT_ENDPOINT_TEMPLATE = "bigtable.{UNIVERSE_DOMAIN}"
+ _DEFAULT_UNIVERSE = "googleapis.com"
+
+ @staticmethod
+ def _use_client_cert_effective():
+ """Returns whether client certificate should be used for mTLS if the
+ google-auth version supports should_use_client_cert automatic mTLS enablement.
+
+ Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var.
+
+ Returns:
+ bool: whether client certificate should be used for mTLS
+ Raises:
+ ValueError: (If using a version of google-auth without should_use_client_cert and
+ GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.)
+ """
+ # check if google-auth version supports should_use_client_cert for automatic mTLS enablement
+ if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER
+ return mtls.should_use_client_cert()
+ else: # pragma: NO COVER
+ # if unsupported, fallback to reading from env var
+ use_client_cert_str = os.getenv(
+ "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"
+ ).lower()
+ if use_client_cert_str not in ("true", "false"):
+ raise ValueError(
+ "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be"
+ " either `true` or `false`"
+ )
+ return use_client_cert_str == "true"
+
@classmethod
def from_service_account_info(cls, info: dict, *args, **kwargs):
"""Creates an instance of this client using the provided credentials
@@ -162,6 +226,30 @@ def transport(self) -> BigtableTransport:
"""
return self._transport
+ @staticmethod
+ def authorized_view_path(
+ project: str,
+ instance: str,
+ table: str,
+ authorized_view: str,
+ ) -> str:
+ """Returns a fully-qualified authorized_view string."""
+ return "projects/{project}/instances/{instance}/tables/{table}/authorizedViews/{authorized_view}".format(
+ project=project,
+ instance=instance,
+ table=table,
+ authorized_view=authorized_view,
+ )
+
+ @staticmethod
+ def parse_authorized_view_path(path: str) -> Dict[str, str]:
+ """Parses a authorized_view path into its component segments."""
+ m = re.match(
+ r"^projects/(?P.+?)/instances/(?P.+?)/tables/(?P.+?)/authorizedViews/(?P.+?)$",
+ path,
+ )
+ return m.groupdict() if m else {}
+
@staticmethod
def instance_path(
project: str,
@@ -179,6 +267,28 @@ def parse_instance_path(path: str) -> Dict[str, str]:
m = re.match(r"^projects/(?P.+?)/instances/(?P.+?)$", path)
return m.groupdict() if m else {}
+ @staticmethod
+ def materialized_view_path(
+ project: str,
+ instance: str,
+ materialized_view: str,
+ ) -> str:
+ """Returns a fully-qualified materialized_view string."""
+ return "projects/{project}/instances/{instance}/materializedViews/{materialized_view}".format(
+ project=project,
+ instance=instance,
+ materialized_view=materialized_view,
+ )
+
+ @staticmethod
+ def parse_materialized_view_path(path: str) -> Dict[str, str]:
+ """Parses a materialized_view path into its component segments."""
+ m = re.match(
+ r"^projects/(?P.+?)/instances/(?P.+?)/materializedViews/(?P.+?)$",
+ path,
+ )
+ return m.groupdict() if m else {}
+
@staticmethod
def table_path(
project: str,
@@ -282,7 +392,7 @@ def parse_common_location_path(path: str) -> Dict[str, str]:
def get_mtls_endpoint_and_cert_source(
cls, client_options: Optional[client_options_lib.ClientOptions] = None
):
- """Return the API endpoint and client cert source for mutual TLS.
+ """Deprecated. Return the API endpoint and client cert source for mutual TLS.
The client cert source is determined in the following order:
(1) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not "true", the
@@ -294,7 +404,7 @@ def get_mtls_endpoint_and_cert_source(
The API endpoint is determined in the following order:
(1) if `client_options.api_endpoint` if provided, use the provided one.
(2) if `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is "always", use the
- default mTLS endpoint; if the environment variabel is "never", use the default API
+ default mTLS endpoint; if the environment variable is "never", use the default API
endpoint; otherwise if client cert source exists, use the default mTLS endpoint, otherwise
use the default API endpoint.
@@ -312,14 +422,15 @@ def get_mtls_endpoint_and_cert_source(
Raises:
google.auth.exceptions.MutualTLSChannelError: If any errors happen.
"""
+
+ warnings.warn(
+ "get_mtls_endpoint_and_cert_source is deprecated. Use the api_endpoint property instead.",
+ DeprecationWarning,
+ )
if client_options is None:
client_options = client_options_lib.ClientOptions()
- use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")
+ use_client_cert = BigtableClient._use_client_cert_effective()
use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto")
- if use_client_cert not in ("true", "false"):
- raise ValueError(
- "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
- )
if use_mtls_endpoint not in ("auto", "never", "always"):
raise MutualTLSChannelError(
"Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
@@ -327,7 +438,7 @@ def get_mtls_endpoint_and_cert_source(
# Figure out the client cert source to use.
client_cert_source = None
- if use_client_cert == "true":
+ if use_client_cert:
if client_options.client_cert_source:
client_cert_source = client_options.client_cert_source
elif mtls.has_default_client_cert_source():
@@ -345,12 +456,173 @@ def get_mtls_endpoint_and_cert_source(
return api_endpoint, client_cert_source
+ @staticmethod
+ def _read_environment_variables():
+ """Returns the environment variables used by the client.
+
+ Returns:
+ Tuple[bool, str, str]: returns the GOOGLE_API_USE_CLIENT_CERTIFICATE,
+ GOOGLE_API_USE_MTLS_ENDPOINT, and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables.
+
+ Raises:
+ ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not
+ any of ["true", "false"].
+ google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT
+ is not any of ["auto", "never", "always"].
+ """
+ use_client_cert = BigtableClient._use_client_cert_effective()
+ use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower()
+ universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN")
+ if use_mtls_endpoint not in ("auto", "never", "always"):
+ raise MutualTLSChannelError(
+ "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
+ )
+ return use_client_cert, use_mtls_endpoint, universe_domain_env
+
+ @staticmethod
+ def _get_client_cert_source(provided_cert_source, use_cert_flag):
+ """Return the client cert source to be used by the client.
+
+ Args:
+ provided_cert_source (bytes): The client certificate source provided.
+ use_cert_flag (bool): A flag indicating whether to use the client certificate.
+
+ Returns:
+ bytes or None: The client cert source to be used by the client.
+ """
+ client_cert_source = None
+ if use_cert_flag:
+ if provided_cert_source:
+ client_cert_source = provided_cert_source
+ elif mtls.has_default_client_cert_source():
+ client_cert_source = mtls.default_client_cert_source()
+ return client_cert_source
+
+ @staticmethod
+ def _get_api_endpoint(
+ api_override, client_cert_source, universe_domain, use_mtls_endpoint
+ ):
+ """Return the API endpoint used by the client.
+
+ Args:
+ api_override (str): The API endpoint override. If specified, this is always
+ the return value of this function and the other arguments are not used.
+ client_cert_source (bytes): The client certificate source used by the client.
+ universe_domain (str): The universe domain used by the client.
+ use_mtls_endpoint (str): How to use the mTLS endpoint, which depends also on the other parameters.
+ Possible values are "always", "auto", or "never".
+
+ Returns:
+ str: The API endpoint to be used by the client.
+ """
+ if api_override is not None:
+ api_endpoint = api_override
+ elif use_mtls_endpoint == "always" or (
+ use_mtls_endpoint == "auto" and client_cert_source
+ ):
+ _default_universe = BigtableClient._DEFAULT_UNIVERSE
+ if universe_domain != _default_universe:
+ raise MutualTLSChannelError(
+ f"mTLS is not supported in any universe other than {_default_universe}."
+ )
+ api_endpoint = BigtableClient.DEFAULT_MTLS_ENDPOINT
+ else:
+ api_endpoint = BigtableClient._DEFAULT_ENDPOINT_TEMPLATE.format(
+ UNIVERSE_DOMAIN=universe_domain
+ )
+ return api_endpoint
+
+ @staticmethod
+ def _get_universe_domain(
+ client_universe_domain: Optional[str], universe_domain_env: Optional[str]
+ ) -> str:
+ """Return the universe domain used by the client.
+
+ Args:
+ client_universe_domain (Optional[str]): The universe domain configured via the client options.
+ universe_domain_env (Optional[str]): The universe domain configured via the "GOOGLE_CLOUD_UNIVERSE_DOMAIN" environment variable.
+
+ Returns:
+ str: The universe domain to be used by the client.
+
+ Raises:
+ ValueError: If the universe domain is an empty string.
+ """
+ universe_domain = BigtableClient._DEFAULT_UNIVERSE
+ if client_universe_domain is not None:
+ universe_domain = client_universe_domain
+ elif universe_domain_env is not None:
+ universe_domain = universe_domain_env
+ if len(universe_domain.strip()) == 0:
+ raise ValueError("Universe Domain cannot be an empty string.")
+ return universe_domain
+
+ def _validate_universe_domain(self):
+ """Validates client's and credentials' universe domains are consistent.
+
+ Returns:
+ bool: True iff the configured universe domain is valid.
+
+ Raises:
+ ValueError: If the configured universe domain is not valid.
+ """
+
+ # NOTE (b/349488459): universe validation is disabled until further notice.
+ return True
+
+ def _add_cred_info_for_auth_errors(
+ self, error: core_exceptions.GoogleAPICallError
+ ) -> None:
+ """Adds credential info string to error details for 401/403/404 errors.
+
+ Args:
+ error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info.
+ """
+ if error.code not in [
+ HTTPStatus.UNAUTHORIZED,
+ HTTPStatus.FORBIDDEN,
+ HTTPStatus.NOT_FOUND,
+ ]:
+ return
+
+ cred = self._transport._credentials
+
+ # get_cred_info is only available in google-auth>=2.35.0
+ if not hasattr(cred, "get_cred_info"):
+ return
+
+ # ignore the type check since pypy test fails when get_cred_info
+ # is not available
+ cred_info = cred.get_cred_info() # type: ignore
+ if cred_info and hasattr(error._details, "append"):
+ error._details.append(json.dumps(cred_info))
+
+ @property
+ def api_endpoint(self):
+ """Return the API endpoint used by the client instance.
+
+ Returns:
+ str: The API endpoint used by the client instance.
+ """
+ return self._api_endpoint
+
+ @property
+ def universe_domain(self) -> str:
+ """Return the universe domain used by the client instance.
+
+ Returns:
+ str: The universe domain used by the client instance.
+ """
+ return self._universe_domain
+
def __init__(
self,
*,
credentials: Optional[ga_credentials.Credentials] = None,
- transport: Union[str, BigtableTransport, None] = None,
- client_options: Optional[client_options_lib.ClientOptions] = None,
+ transport: Optional[
+ Union[str, BigtableTransport, Callable[..., BigtableTransport]]
+ ] = None,
+ client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None,
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
"""Instantiates the bigtable client.
@@ -361,25 +633,37 @@ def __init__(
credentials identify the application to the service; if none
are specified, the client will attempt to ascertain the
credentials from the environment.
- transport (Union[str, BigtableTransport]): The
- transport to use. If set to None, a transport is chosen
- automatically.
- client_options (google.api_core.client_options.ClientOptions): Custom options for the
- client. It won't take effect if a ``transport`` instance is provided.
- (1) The ``api_endpoint`` property can be used to override the
- default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
- environment variable can also be used to override the endpoint:
+ transport (Optional[Union[str,BigtableTransport,Callable[..., BigtableTransport]]]):
+ The transport to use, or a Callable that constructs and returns a new transport.
+ If a Callable is given, it will be called with the same set of initialization
+ arguments as used in the BigtableTransport constructor.
+ If set to None, a transport is chosen automatically.
+ client_options (Optional[Union[google.api_core.client_options.ClientOptions, dict]]):
+ Custom options for the client.
+
+ 1. The ``api_endpoint`` property can be used to override the
+ default endpoint provided by the client when ``transport`` is
+ not explicitly provided. Only if this property is not set and
+ ``transport`` was not explicitly provided, the endpoint is
+ determined by the GOOGLE_API_USE_MTLS_ENDPOINT environment
+ variable, which have one of the following values:
"always" (always use the default mTLS endpoint), "never" (always
- use the default regular endpoint) and "auto" (auto switch to the
- default mTLS endpoint if client certificate is present, this is
- the default value). However, the ``api_endpoint`` property takes
- precedence if provided.
- (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
+ use the default regular endpoint) and "auto" (auto-switch to the
+ default mTLS endpoint if client certificate is present; this is
+ the default value).
+
+ 2. If the GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
is "true", then the ``client_cert_source`` property can be used
- to provide client certificate for mutual TLS transport. If
+ to provide a client certificate for mTLS transport. If
not provided, the default SSL client certificate will be used if
present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
set, no client certificate will be used.
+
+ 3. The ``universe_domain`` property can be used to override the
+ default "googleapis.com" universe. Note that the ``api_endpoint``
+ property still takes precedence; and ``universe_domain`` is
+ currently not supported for mTLS.
+
client_info (google.api_core.gapic_v1.client_info.ClientInfo):
The client info used to send a user-agent string along with
API requests. If ``None``, then default info will be used.
@@ -390,16 +674,38 @@ def __init__(
google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
creation failed for any reason.
"""
- if isinstance(client_options, dict):
- client_options = client_options_lib.from_dict(client_options)
- if client_options is None:
- client_options = client_options_lib.ClientOptions()
+ self._client_options = client_options
+ if isinstance(self._client_options, dict):
+ self._client_options = client_options_lib.from_dict(self._client_options)
+ if self._client_options is None:
+ self._client_options = client_options_lib.ClientOptions()
+ self._client_options = cast(
+ client_options_lib.ClientOptions, self._client_options
+ )
+
+ universe_domain_opt = getattr(self._client_options, "universe_domain", None)
- api_endpoint, client_cert_source_func = self.get_mtls_endpoint_and_cert_source(
- client_options
+ (
+ self._use_client_cert,
+ self._use_mtls_endpoint,
+ self._universe_domain_env,
+ ) = BigtableClient._read_environment_variables()
+ self._client_cert_source = BigtableClient._get_client_cert_source(
+ self._client_options.client_cert_source, self._use_client_cert
+ )
+ self._universe_domain = BigtableClient._get_universe_domain(
+ universe_domain_opt, self._universe_domain_env
)
+ self._api_endpoint = None # updated below, depending on `transport`
- api_key_value = getattr(client_options, "api_key", None)
+ # Initialize the universe domain validation.
+ self._is_universe_domain_valid = False
+
+ if CLIENT_LOGGING_SUPPORTED: # pragma: NO COVER
+ # Setup logging.
+ client_logging.initialize_logging()
+
+ api_key_value = getattr(self._client_options, "api_key", None)
if api_key_value and credentials:
raise ValueError(
"client_options.api_key and credentials are mutually exclusive"
@@ -408,20 +714,30 @@ def __init__(
# Save or instantiate the transport.
# Ordinarily, we provide the transport, but allowing a custom transport
# instance provides an extensibility point for unusual situations.
- if isinstance(transport, BigtableTransport):
+ transport_provided = isinstance(transport, BigtableTransport)
+ if transport_provided:
# transport is a BigtableTransport instance.
- if credentials or client_options.credentials_file or api_key_value:
+ if credentials or self._client_options.credentials_file or api_key_value:
raise ValueError(
"When providing a transport instance, "
"provide its credentials directly."
)
- if client_options.scopes:
+ if self._client_options.scopes:
raise ValueError(
"When providing a transport instance, provide its scopes "
"directly."
)
- self._transport = transport
- else:
+ self._transport = cast(BigtableTransport, transport)
+ self._api_endpoint = self._transport.host
+
+ self._api_endpoint = self._api_endpoint or BigtableClient._get_api_endpoint(
+ self._client_options.api_endpoint,
+ self._client_cert_source,
+ self._universe_domain,
+ self._use_mtls_endpoint,
+ )
+
+ if not transport_provided:
import google.auth._default # type: ignore
if api_key_value and hasattr(
@@ -431,27 +747,58 @@ def __init__(
api_key_value
)
- Transport = type(self).get_transport_class(transport)
- self._transport = Transport(
+ transport_init: Union[
+ Type[BigtableTransport], Callable[..., BigtableTransport]
+ ] = (
+ BigtableClient.get_transport_class(transport)
+ if isinstance(transport, str) or transport is None
+ else cast(Callable[..., BigtableTransport], transport)
+ )
+ # initialize with the provided callable or the passed in class
+ self._transport = transport_init(
credentials=credentials,
- credentials_file=client_options.credentials_file,
- host=api_endpoint,
- scopes=client_options.scopes,
- client_cert_source_for_mtls=client_cert_source_func,
- quota_project_id=client_options.quota_project_id,
+ credentials_file=self._client_options.credentials_file,
+ host=self._api_endpoint,
+ scopes=self._client_options.scopes,
+ client_cert_source_for_mtls=self._client_cert_source,
+ quota_project_id=self._client_options.quota_project_id,
client_info=client_info,
always_use_jwt_access=True,
+ api_audience=self._client_options.api_audience,
)
+ if "async" not in str(self._transport):
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ std_logging.DEBUG
+ ): # pragma: NO COVER
+ _LOGGER.debug(
+ "Created client `google.bigtable_v2.BigtableClient`.",
+ extra={
+ "serviceName": "google.bigtable.v2.Bigtable",
+ "universeDomain": getattr(
+ self._transport._credentials, "universe_domain", ""
+ ),
+ "credentialsType": f"{type(self._transport._credentials).__module__}.{type(self._transport._credentials).__qualname__}",
+ "credentialsInfo": getattr(
+ self.transport._credentials, "get_cred_info", lambda: None
+ )(),
+ }
+ if hasattr(self._transport, "_credentials")
+ else {
+ "serviceName": "google.bigtable.v2.Bigtable",
+ "credentialsType": None,
+ },
+ )
+
def read_rows(
self,
- request: Union[bigtable.ReadRowsRequest, dict] = None,
+ request: Optional[Union[bigtable.ReadRowsRequest, dict]] = None,
*,
- table_name: str = None,
- app_profile_id: str = None,
+ table_name: Optional[str] = None,
+ app_profile_id: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> Iterable[bigtable.ReadRowsResponse]:
r"""Streams back the contents of all requested rows in
key order, optionally applying the same Reader filter to
@@ -465,8 +812,10 @@ def read_rows(
The request object. Request message for
Bigtable.ReadRows.
table_name (str):
- Required. The unique name of the table from which to
- read. Values are of the form
+ Optional. The unique name of the table from which to
+ read.
+
+ Values are of the form
``projects//instances//tables/``.
This corresponds to the ``table_name`` field
@@ -484,8 +833,10 @@ def read_rows(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
Iterable[google.cloud.bigtable_v2.types.ReadRowsResponse]:
@@ -494,19 +845,20 @@ def read_rows(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([table_name, app_profile_id])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [table_name, app_profile_id]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable.ReadRowsRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
if not isinstance(request, bigtable.ReadRowsRequest):
request = bigtable.ReadRowsRequest(request)
# If we have keyword arguments corresponding to fields on the
@@ -529,14 +881,31 @@ def read_rows(
if regex_match and regex_match.group("table_name"):
header_params["table_name"] = regex_match.group("table_name")
- if request.app_profile_id:
+ if True: # always attach app_profile_id, even if empty string
header_params["app_profile_id"] = request.app_profile_id
+ routing_param_regex = re.compile(
+ "^(?Pprojects/[^/]+/instances/[^/]+/tables/[^/]+)(?:/.*)?$"
+ )
+ regex_match = routing_param_regex.match(request.authorized_view_name)
+ if regex_match and regex_match.group("table_name"):
+ header_params["table_name"] = regex_match.group("table_name")
+
+ routing_param_regex = re.compile(
+ "^(?Pprojects/[^/]+/instances/[^/]+)(?:/.*)?$"
+ )
+ regex_match = routing_param_regex.match(request.materialized_view_name)
+ if regex_match and regex_match.group("name"):
+ header_params["name"] = regex_match.group("name")
+
if header_params:
metadata = tuple(metadata) + (
gapic_v1.routing_header.to_grpc_metadata(header_params),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -550,13 +919,13 @@ def read_rows(
def sample_row_keys(
self,
- request: Union[bigtable.SampleRowKeysRequest, dict] = None,
+ request: Optional[Union[bigtable.SampleRowKeysRequest, dict]] = None,
*,
- table_name: str = None,
- app_profile_id: str = None,
+ table_name: Optional[str] = None,
+ app_profile_id: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> Iterable[bigtable.SampleRowKeysResponse]:
r"""Returns a sample of row keys in the table. The
returned row keys will delimit contiguous sections of
@@ -569,8 +938,10 @@ def sample_row_keys(
The request object. Request message for
Bigtable.SampleRowKeys.
table_name (str):
- Required. The unique name of the table from which to
- sample row keys. Values are of the form
+ Optional. The unique name of the table from which to
+ sample row keys.
+
+ Values are of the form
``projects//instances//tables/``.
This corresponds to the ``table_name`` field
@@ -588,8 +959,10 @@ def sample_row_keys(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
Iterable[google.cloud.bigtable_v2.types.SampleRowKeysResponse]:
@@ -598,19 +971,20 @@ def sample_row_keys(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([table_name, app_profile_id])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [table_name, app_profile_id]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable.SampleRowKeysRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
if not isinstance(request, bigtable.SampleRowKeysRequest):
request = bigtable.SampleRowKeysRequest(request)
# If we have keyword arguments corresponding to fields on the
@@ -633,14 +1007,31 @@ def sample_row_keys(
if regex_match and regex_match.group("table_name"):
header_params["table_name"] = regex_match.group("table_name")
- if request.app_profile_id:
+ if True: # always attach app_profile_id, even if empty string
header_params["app_profile_id"] = request.app_profile_id
+ routing_param_regex = re.compile(
+ "^(?Pprojects/[^/]+/instances/[^/]+/tables/[^/]+)(?:/.*)?$"
+ )
+ regex_match = routing_param_regex.match(request.authorized_view_name)
+ if regex_match and regex_match.group("table_name"):
+ header_params["table_name"] = regex_match.group("table_name")
+
+ routing_param_regex = re.compile(
+ "^(?Pprojects/[^/]+/instances/[^/]+)(?:/.*)?$"
+ )
+ regex_match = routing_param_regex.match(request.materialized_view_name)
+ if regex_match and regex_match.group("name"):
+ header_params["name"] = regex_match.group("name")
+
if header_params:
metadata = tuple(metadata) + (
gapic_v1.routing_header.to_grpc_metadata(header_params),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -654,15 +1045,15 @@ def sample_row_keys(
def mutate_row(
self,
- request: Union[bigtable.MutateRowRequest, dict] = None,
+ request: Optional[Union[bigtable.MutateRowRequest, dict]] = None,
*,
- table_name: str = None,
- row_key: bytes = None,
- mutations: Sequence[data.Mutation] = None,
- app_profile_id: str = None,
+ table_name: Optional[str] = None,
+ row_key: Optional[bytes] = None,
+ mutations: Optional[MutableSequence[data.Mutation]] = None,
+ app_profile_id: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> bigtable.MutateRowResponse:
r"""Mutates a row atomically. Cells already present in the row are
left unchanged unless explicitly changed by ``mutation``.
@@ -672,8 +1063,10 @@ def mutate_row(
The request object. Request message for
Bigtable.MutateRow.
table_name (str):
- Required. The unique name of the table to which the
- mutation should be applied. Values are of the form
+ Optional. The unique name of the table to which the
+ mutation should be applied.
+
+ Values are of the form
``projects//instances//tables/``.
This corresponds to the ``table_name`` field
@@ -686,7 +1079,7 @@ def mutate_row(
This corresponds to the ``row_key`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- mutations (Sequence[google.cloud.bigtable_v2.types.Mutation]):
+ mutations (MutableSequence[google.cloud.bigtable_v2.types.Mutation]):
Required. Changes to be atomically
applied to the specified row. Entries
are applied in order, meaning that
@@ -709,8 +1102,10 @@ def mutate_row(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_v2.types.MutateRowResponse:
@@ -719,19 +1114,20 @@ def mutate_row(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([table_name, row_key, mutations, app_profile_id])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [table_name, row_key, mutations, app_profile_id]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable.MutateRowRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
if not isinstance(request, bigtable.MutateRowRequest):
request = bigtable.MutateRowRequest(request)
# If we have keyword arguments corresponding to fields on the
@@ -758,14 +1154,24 @@ def mutate_row(
if regex_match and regex_match.group("table_name"):
header_params["table_name"] = regex_match.group("table_name")
- if request.app_profile_id:
+ if True: # always attach app_profile_id, even if empty string
header_params["app_profile_id"] = request.app_profile_id
+ routing_param_regex = re.compile(
+ "^(?Pprojects/[^/]+/instances/[^/]+/tables/[^/]+)(?:/.*)?$"
+ )
+ regex_match = routing_param_regex.match(request.authorized_view_name)
+ if regex_match and regex_match.group("table_name"):
+ header_params["table_name"] = regex_match.group("table_name")
+
if header_params:
metadata = tuple(metadata) + (
gapic_v1.routing_header.to_grpc_metadata(header_params),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -779,14 +1185,14 @@ def mutate_row(
def mutate_rows(
self,
- request: Union[bigtable.MutateRowsRequest, dict] = None,
+ request: Optional[Union[bigtable.MutateRowsRequest, dict]] = None,
*,
- table_name: str = None,
- entries: Sequence[bigtable.MutateRowsRequest.Entry] = None,
- app_profile_id: str = None,
+ table_name: Optional[str] = None,
+ entries: Optional[MutableSequence[bigtable.MutateRowsRequest.Entry]] = None,
+ app_profile_id: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> Iterable[bigtable.MutateRowsResponse]:
r"""Mutates multiple rows in a batch. Each individual row
is mutated atomically as in MutateRow, but the entire
@@ -797,14 +1203,16 @@ def mutate_rows(
The request object. Request message for
BigtableService.MutateRows.
table_name (str):
- Required. The unique name of the
- table to which the mutations should be
- applied.
+ Optional. The unique name of the table to which the
+ mutations should be applied.
+
+ Values are of the form
+ ``projects//instances//tables/``.
This corresponds to the ``table_name`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- entries (Sequence[google.cloud.bigtable_v2.types.MutateRowsRequest.Entry]):
+ entries (MutableSequence[google.cloud.bigtable_v2.types.MutateRowsRequest.Entry]):
Required. The row keys and
corresponding mutations to be applied in
bulk. Each entry is applied as an atomic
@@ -830,8 +1238,10 @@ def mutate_rows(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
Iterable[google.cloud.bigtable_v2.types.MutateRowsResponse]:
@@ -840,19 +1250,20 @@ def mutate_rows(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([table_name, entries, app_profile_id])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [table_name, entries, app_profile_id]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable.MutateRowsRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
if not isinstance(request, bigtable.MutateRowsRequest):
request = bigtable.MutateRowsRequest(request)
# If we have keyword arguments corresponding to fields on the
@@ -877,14 +1288,24 @@ def mutate_rows(
if regex_match and regex_match.group("table_name"):
header_params["table_name"] = regex_match.group("table_name")
- if request.app_profile_id:
+ if True: # always attach app_profile_id, even if empty string
header_params["app_profile_id"] = request.app_profile_id
+ routing_param_regex = re.compile(
+ "^(?Pprojects/[^/]+/instances/[^/]+/tables/[^/]+)(?:/.*)?$"
+ )
+ regex_match = routing_param_regex.match(request.authorized_view_name)
+ if regex_match and regex_match.group("table_name"):
+ header_params["table_name"] = regex_match.group("table_name")
+
if header_params:
metadata = tuple(metadata) + (
gapic_v1.routing_header.to_grpc_metadata(header_params),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -898,17 +1319,17 @@ def mutate_rows(
def check_and_mutate_row(
self,
- request: Union[bigtable.CheckAndMutateRowRequest, dict] = None,
+ request: Optional[Union[bigtable.CheckAndMutateRowRequest, dict]] = None,
*,
- table_name: str = None,
- row_key: bytes = None,
- predicate_filter: data.RowFilter = None,
- true_mutations: Sequence[data.Mutation] = None,
- false_mutations: Sequence[data.Mutation] = None,
- app_profile_id: str = None,
+ table_name: Optional[str] = None,
+ row_key: Optional[bytes] = None,
+ predicate_filter: Optional[data.RowFilter] = None,
+ true_mutations: Optional[MutableSequence[data.Mutation]] = None,
+ false_mutations: Optional[MutableSequence[data.Mutation]] = None,
+ app_profile_id: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> bigtable.CheckAndMutateRowResponse:
r"""Mutates a row atomically based on the output of a
predicate Reader filter.
@@ -918,9 +1339,10 @@ def check_and_mutate_row(
The request object. Request message for
Bigtable.CheckAndMutateRow.
table_name (str):
- Required. The unique name of the table to which the
- conditional mutation should be applied. Values are of
- the form
+ Optional. The unique name of the table to which the
+ conditional mutation should be applied.
+
+ Values are of the form
``projects//instances//tables/``.
This corresponds to the ``table_name`` field
@@ -944,7 +1366,7 @@ def check_and_mutate_row(
This corresponds to the ``predicate_filter`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- true_mutations (Sequence[google.cloud.bigtable_v2.types.Mutation]):
+ true_mutations (MutableSequence[google.cloud.bigtable_v2.types.Mutation]):
Changes to be atomically applied to the specified row if
``predicate_filter`` yields at least one cell when
applied to ``row_key``. Entries are applied in order,
@@ -955,7 +1377,7 @@ def check_and_mutate_row(
This corresponds to the ``true_mutations`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- false_mutations (Sequence[google.cloud.bigtable_v2.types.Mutation]):
+ false_mutations (MutableSequence[google.cloud.bigtable_v2.types.Mutation]):
Changes to be atomically applied to the specified row if
``predicate_filter`` does not yield any cells when
applied to ``row_key``. Entries are applied in order,
@@ -978,8 +1400,10 @@ def check_and_mutate_row(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_v2.types.CheckAndMutateRowResponse:
@@ -988,17 +1412,18 @@ def check_and_mutate_row(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any(
- [
- table_name,
- row_key,
- predicate_filter,
- true_mutations,
- false_mutations,
- app_profile_id,
- ]
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [
+ table_name,
+ row_key,
+ predicate_filter,
+ true_mutations,
+ false_mutations,
+ app_profile_id,
+ ]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
)
if request is not None and has_flattened_params:
raise ValueError(
@@ -1006,10 +1431,8 @@ def check_and_mutate_row(
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable.CheckAndMutateRowRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
if not isinstance(request, bigtable.CheckAndMutateRowRequest):
request = bigtable.CheckAndMutateRowRequest(request)
# If we have keyword arguments corresponding to fields on the
@@ -1040,14 +1463,24 @@ def check_and_mutate_row(
if regex_match and regex_match.group("table_name"):
header_params["table_name"] = regex_match.group("table_name")
- if request.app_profile_id:
+ if True: # always attach app_profile_id, even if empty string
header_params["app_profile_id"] = request.app_profile_id
+ routing_param_regex = re.compile(
+ "^(?Pprojects/[^/]+/instances/[^/]+/tables/[^/]+)(?:/.*)?$"
+ )
+ regex_match = routing_param_regex.match(request.authorized_view_name)
+ if regex_match and regex_match.group("table_name"):
+ header_params["table_name"] = regex_match.group("table_name")
+
if header_params:
metadata = tuple(metadata) + (
gapic_v1.routing_header.to_grpc_metadata(header_params),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -1061,13 +1494,13 @@ def check_and_mutate_row(
def ping_and_warm(
self,
- request: Union[bigtable.PingAndWarmRequest, dict] = None,
+ request: Optional[Union[bigtable.PingAndWarmRequest, dict]] = None,
*,
- name: str = None,
- app_profile_id: str = None,
+ name: Optional[str] = None,
+ app_profile_id: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> bigtable.PingAndWarmResponse:
r"""Warm up associated instance metadata for this
connection. This call is not required but may be useful
@@ -1075,8 +1508,8 @@ def ping_and_warm(
Args:
request (Union[google.cloud.bigtable_v2.types.PingAndWarmRequest, dict]):
- The request object. Request message for client
- connection keep-alive and warming.
+ The request object. Request message for client connection
+ keep-alive and warming.
name (str):
Required. The unique name of the instance to check
permissions for as well as respond. Values are of the
@@ -1097,8 +1530,10 @@ def ping_and_warm(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_v2.types.PingAndWarmResponse:
@@ -1108,19 +1543,20 @@ def ping_and_warm(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([name, app_profile_id])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [name, app_profile_id]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable.PingAndWarmRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
if not isinstance(request, bigtable.PingAndWarmRequest):
request = bigtable.PingAndWarmRequest(request)
# If we have keyword arguments corresponding to fields on the
@@ -1141,7 +1577,7 @@ def ping_and_warm(
if regex_match and regex_match.group("name"):
header_params["name"] = regex_match.group("name")
- if request.app_profile_id:
+ if True: # always attach app_profile_id, even if empty string
header_params["app_profile_id"] = request.app_profile_id
if header_params:
@@ -1149,6 +1585,9 @@ def ping_and_warm(
gapic_v1.routing_header.to_grpc_metadata(header_params),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -1162,15 +1601,15 @@ def ping_and_warm(
def read_modify_write_row(
self,
- request: Union[bigtable.ReadModifyWriteRowRequest, dict] = None,
+ request: Optional[Union[bigtable.ReadModifyWriteRowRequest, dict]] = None,
*,
- table_name: str = None,
- row_key: bytes = None,
- rules: Sequence[data.ReadModifyWriteRule] = None,
- app_profile_id: str = None,
+ table_name: Optional[str] = None,
+ row_key: Optional[bytes] = None,
+ rules: Optional[MutableSequence[data.ReadModifyWriteRule]] = None,
+ app_profile_id: Optional[str] = None,
retry: OptionalRetry = gapic_v1.method.DEFAULT,
- timeout: float = None,
- metadata: Sequence[Tuple[str, str]] = (),
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
) -> bigtable.ReadModifyWriteRowResponse:
r"""Modifies a row atomically on the server. The method
reads the latest existing timestamp and value from the
@@ -1185,9 +1624,10 @@ def read_modify_write_row(
The request object. Request message for
Bigtable.ReadModifyWriteRow.
table_name (str):
- Required. The unique name of the table to which the
- read/modify/write rules should be applied. Values are of
- the form
+ Optional. The unique name of the table to which the
+ read/modify/write rules should be applied.
+
+ Values are of the form
``projects//instances//tables/``.
This corresponds to the ``table_name`` field
@@ -1201,13 +1641,15 @@ def read_modify_write_row(
This corresponds to the ``row_key`` field
on the ``request`` instance; if ``request`` is provided, this
should not be set.
- rules (Sequence[google.cloud.bigtable_v2.types.ReadModifyWriteRule]):
+ rules (MutableSequence[google.cloud.bigtable_v2.types.ReadModifyWriteRule]):
Required. Rules specifying how the
specified row's contents are to be
transformed into writes. Entries are
applied in order, meaning that earlier
rules will affect the results of later
- ones.
+ ones. At least one entry must be
+ specified, and there can be at most
+ 100000 rules.
This corresponds to the ``rules`` field
on the ``request`` instance; if ``request`` is provided, this
@@ -1224,8 +1666,10 @@ def read_modify_write_row(
retry (google.api_core.retry.Retry): Designation of what errors, if any,
should be retried.
timeout (float): The timeout for this request.
- metadata (Sequence[Tuple[str, str]]): Strings which should be
- sent along with the request as metadata.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
Returns:
google.cloud.bigtable_v2.types.ReadModifyWriteRowResponse:
@@ -1234,19 +1678,20 @@ def read_modify_write_row(
"""
# Create or coerce a protobuf request object.
- # Quick check: If we got a request object, we should *not* have
- # gotten any keyword arguments that map to the request.
- has_flattened_params = any([table_name, row_key, rules, app_profile_id])
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [table_name, row_key, rules, app_profile_id]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
if request is not None and has_flattened_params:
raise ValueError(
"If the `request` argument is set, then none of "
"the individual field arguments should be set."
)
- # Minor optimization to avoid making a copy if the user passes
- # in a bigtable.ReadModifyWriteRowRequest.
- # There's no risk of modifying the input as we've already verified
- # there are no flattened fields.
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
if not isinstance(request, bigtable.ReadModifyWriteRowRequest):
request = bigtable.ReadModifyWriteRowRequest(request)
# If we have keyword arguments corresponding to fields on the
@@ -1273,14 +1718,24 @@ def read_modify_write_row(
if regex_match and regex_match.group("table_name"):
header_params["table_name"] = regex_match.group("table_name")
- if request.app_profile_id:
+ if True: # always attach app_profile_id, even if empty string
header_params["app_profile_id"] = request.app_profile_id
+ routing_param_regex = re.compile(
+ "^(?Pprojects/[^/]+/instances/[^/]+/tables/[^/]+)(?:/.*)?$"
+ )
+ regex_match = routing_param_regex.match(request.authorized_view_name)
+ if regex_match and regex_match.group("table_name"):
+ header_params["table_name"] = regex_match.group("table_name")
+
if header_params:
metadata = tuple(metadata) + (
gapic_v1.routing_header.to_grpc_metadata(header_params),
)
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
# Send the request.
response = rpc(
request,
@@ -1292,7 +1747,457 @@ def read_modify_write_row(
# Done; return the response.
return response
- def __enter__(self):
+ def generate_initial_change_stream_partitions(
+ self,
+ request: Optional[
+ Union[bigtable.GenerateInitialChangeStreamPartitionsRequest, dict]
+ ] = None,
+ *,
+ table_name: Optional[str] = None,
+ app_profile_id: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> Iterable[bigtable.GenerateInitialChangeStreamPartitionsResponse]:
+ r"""Returns the current list of partitions that make up the table's
+ change stream. The union of partitions will cover the entire
+ keyspace. Partitions can be read with ``ReadChangeStream``.
+ NOTE: This API is only intended to be used by Apache Beam
+ BigtableIO.
+
+ Args:
+ request (Union[google.cloud.bigtable_v2.types.GenerateInitialChangeStreamPartitionsRequest, dict]):
+ The request object. NOTE: This API is intended to be used
+ by Apache Beam BigtableIO. Request
+ message for
+ Bigtable.GenerateInitialChangeStreamPartitions.
+ table_name (str):
+ Required. The unique name of the table from which to get
+ change stream partitions. Values are of the form
+ ``projects//instances//tables/``.
+ Change streaming must be enabled on the table.
+
+ This corresponds to the ``table_name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ app_profile_id (str):
+ This value specifies routing for
+ replication. If not specified, the
+ "default" application profile will be
+ used. Single cluster routing must be
+ configured on the profile.
+
+ This corresponds to the ``app_profile_id`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ Iterable[google.cloud.bigtable_v2.types.GenerateInitialChangeStreamPartitionsResponse]:
+ NOTE: This API is intended to be used
+ by Apache Beam BigtableIO. Response
+ message for
+ Bigtable.GenerateInitialChangeStreamPartitions.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [table_name, app_profile_id]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(
+ request, bigtable.GenerateInitialChangeStreamPartitionsRequest
+ ):
+ request = bigtable.GenerateInitialChangeStreamPartitionsRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if table_name is not None:
+ request.table_name = table_name
+ if app_profile_id is not None:
+ request.app_profile_id = app_profile_id
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[
+ self._transport.generate_initial_change_stream_partitions
+ ]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata(
+ (("table_name", request.table_name),)
+ ),
+ )
+
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
+ # Send the request.
+ response = rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def read_change_stream(
+ self,
+ request: Optional[Union[bigtable.ReadChangeStreamRequest, dict]] = None,
+ *,
+ table_name: Optional[str] = None,
+ app_profile_id: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> Iterable[bigtable.ReadChangeStreamResponse]:
+ r"""Reads changes from a table's change stream. Changes
+ will reflect both user-initiated mutations and mutations
+ that are caused by garbage collection.
+ NOTE: This API is only intended to be used by Apache
+ Beam BigtableIO.
+
+ Args:
+ request (Union[google.cloud.bigtable_v2.types.ReadChangeStreamRequest, dict]):
+ The request object. NOTE: This API is intended to be used
+ by Apache Beam BigtableIO. Request
+ message for Bigtable.ReadChangeStream.
+ table_name (str):
+ Required. The unique name of the table from which to
+ read a change stream. Values are of the form
+ ``projects//instances//tables/``.
+ Change streaming must be enabled on the table.
+
+ This corresponds to the ``table_name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ app_profile_id (str):
+ This value specifies routing for
+ replication. If not specified, the
+ "default" application profile will be
+ used. Single cluster routing must be
+ configured on the profile.
+
+ This corresponds to the ``app_profile_id`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ Iterable[google.cloud.bigtable_v2.types.ReadChangeStreamResponse]:
+ NOTE: This API is intended to be used
+ by Apache Beam BigtableIO. Response
+ message for Bigtable.ReadChangeStream.
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [table_name, app_profile_id]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable.ReadChangeStreamRequest):
+ request = bigtable.ReadChangeStreamRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if table_name is not None:
+ request.table_name = table_name
+ if app_profile_id is not None:
+ request.app_profile_id = app_profile_id
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.read_change_stream]
+
+ # Certain fields should be provided within the metadata header;
+ # add these here.
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata(
+ (("table_name", request.table_name),)
+ ),
+ )
+
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
+ # Send the request.
+ response = rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def prepare_query(
+ self,
+ request: Optional[Union[bigtable.PrepareQueryRequest, dict]] = None,
+ *,
+ instance_name: Optional[str] = None,
+ query: Optional[str] = None,
+ app_profile_id: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> bigtable.PrepareQueryResponse:
+ r"""Prepares a GoogleSQL query for execution on a
+ particular Bigtable instance.
+
+ Args:
+ request (Union[google.cloud.bigtable_v2.types.PrepareQueryRequest, dict]):
+ The request object. Request message for
+ Bigtable.PrepareQuery
+ instance_name (str):
+ Required. The unique name of the instance against which
+ the query should be executed. Values are of the form
+ ``projects//instances/``
+
+ This corresponds to the ``instance_name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ query (str):
+ Required. The query string.
+ This corresponds to the ``query`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ app_profile_id (str):
+ Optional. This value specifies routing for preparing the
+ query. Note that this ``app_profile_id`` is only used
+ for preparing the query. The actual query execution will
+ use the app profile specified in the
+ ``ExecuteQueryRequest``. If not specified, the
+ ``default`` application profile will be used.
+
+ This corresponds to the ``app_profile_id`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ google.cloud.bigtable_v2.types.PrepareQueryResponse:
+ Response message for
+ Bigtable.PrepareQueryResponse
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [instance_name, query, app_profile_id]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable.PrepareQueryRequest):
+ request = bigtable.PrepareQueryRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if instance_name is not None:
+ request.instance_name = instance_name
+ if query is not None:
+ request.query = query
+ if app_profile_id is not None:
+ request.app_profile_id = app_profile_id
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.prepare_query]
+
+ header_params = {}
+
+ routing_param_regex = re.compile("^(?Pprojects/[^/]+/instances/[^/]+)$")
+ regex_match = routing_param_regex.match(request.instance_name)
+ if regex_match and regex_match.group("name"):
+ header_params["name"] = regex_match.group("name")
+
+ if True: # always attach app_profile_id, even if empty string
+ header_params["app_profile_id"] = request.app_profile_id
+
+ if header_params:
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata(header_params),
+ )
+
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
+ # Send the request.
+ response = rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def execute_query(
+ self,
+ request: Optional[Union[bigtable.ExecuteQueryRequest, dict]] = None,
+ *,
+ instance_name: Optional[str] = None,
+ query: Optional[str] = None,
+ app_profile_id: Optional[str] = None,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Union[float, object] = gapic_v1.method.DEFAULT,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> Iterable[bigtable.ExecuteQueryResponse]:
+ r"""Executes a SQL query against a particular Bigtable
+ instance.
+
+ Args:
+ request (Union[google.cloud.bigtable_v2.types.ExecuteQueryRequest, dict]):
+ The request object. Request message for
+ Bigtable.ExecuteQuery
+ instance_name (str):
+ Required. The unique name of the instance against which
+ the query should be executed. Values are of the form
+ ``projects//instances/``
+
+ This corresponds to the ``instance_name`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ query (str):
+ Required. The query string.
+
+ Exactly one of ``query`` and ``prepared_query`` is
+ required. Setting both or neither is an
+ ``INVALID_ARGUMENT``.
+
+ This corresponds to the ``query`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ app_profile_id (str):
+ Optional. This value specifies routing for replication.
+ If not specified, the ``default`` application profile
+ will be used.
+
+ This corresponds to the ``app_profile_id`` field
+ on the ``request`` instance; if ``request`` is provided, this
+ should not be set.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ Iterable[google.cloud.bigtable_v2.types.ExecuteQueryResponse]:
+ Response message for
+ Bigtable.ExecuteQuery
+
+ """
+ # Create or coerce a protobuf request object.
+ # - Quick check: If we got a request object, we should *not* have
+ # gotten any keyword arguments that map to the request.
+ flattened_params = [instance_name, query, app_profile_id]
+ has_flattened_params = (
+ len([param for param in flattened_params if param is not None]) > 0
+ )
+ if request is not None and has_flattened_params:
+ raise ValueError(
+ "If the `request` argument is set, then none of "
+ "the individual field arguments should be set."
+ )
+
+ # - Use the request object if provided (there's no risk of modifying the input as
+ # there are no flattened fields), or create one.
+ if not isinstance(request, bigtable.ExecuteQueryRequest):
+ request = bigtable.ExecuteQueryRequest(request)
+ # If we have keyword arguments corresponding to fields on the
+ # request, apply these.
+ if instance_name is not None:
+ request.instance_name = instance_name
+ if query is not None:
+ request.query = query
+ if app_profile_id is not None:
+ request.app_profile_id = app_profile_id
+
+ # Wrap the RPC method; this adds retry and timeout information,
+ # and friendly error handling.
+ rpc = self._transport._wrapped_methods[self._transport.execute_query]
+
+ header_params = {}
+
+ routing_param_regex = re.compile("^(?Pprojects/[^/]+/instances/[^/]+)$")
+ regex_match = routing_param_regex.match(request.instance_name)
+ if regex_match and regex_match.group("name"):
+ header_params["name"] = regex_match.group("name")
+
+ if True: # always attach app_profile_id, even if empty string
+ header_params["app_profile_id"] = request.app_profile_id
+
+ if header_params:
+ metadata = tuple(metadata) + (
+ gapic_v1.routing_header.to_grpc_metadata(header_params),
+ )
+
+ # Validate the universe domain.
+ self._validate_universe_domain()
+
+ # Send the request.
+ response = rpc(
+ request,
+ retry=retry,
+ timeout=timeout,
+ metadata=metadata,
+ )
+
+ # Done; return the response.
+ return response
+
+ def __enter__(self) -> "BigtableClient":
return self
def __exit__(self, type, value, traceback):
@@ -1306,14 +2211,11 @@ def __exit__(self, type, value, traceback):
self.transport.close()
-try:
- DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
- gapic_version=pkg_resources.get_distribution(
- "google-cloud-bigtable",
- ).version,
- )
-except pkg_resources.DistributionNotFound:
- DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
+DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
+ gapic_version=package_version.__version__
+)
+if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER
+ DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__
__all__ = ("BigtableClient",)
diff --git a/google/cloud/bigtable_v2/services/bigtable/transports/README.rst b/google/cloud/bigtable_v2/services/bigtable/transports/README.rst
new file mode 100644
index 000000000..254812cd3
--- /dev/null
+++ b/google/cloud/bigtable_v2/services/bigtable/transports/README.rst
@@ -0,0 +1,9 @@
+
+transport inheritance structure
+_______________________________
+
+`BigtableTransport` is the ABC for all transports.
+- public child `BigtableGrpcTransport` for sync gRPC transport (defined in `grpc.py`).
+- public child `BigtableGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`).
+- private child `_BaseBigtableRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`).
+- public child `BigtableRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`).
diff --git a/google/cloud/bigtable_v2/services/bigtable/transports/__init__.py b/google/cloud/bigtable_v2/services/bigtable/transports/__init__.py
index 67a9abdf9..b35e85534 100644
--- a/google/cloud/bigtable_v2/services/bigtable/transports/__init__.py
+++ b/google/cloud/bigtable_v2/services/bigtable/transports/__init__.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -19,15 +19,20 @@
from .base import BigtableTransport
from .grpc import BigtableGrpcTransport
from .grpc_asyncio import BigtableGrpcAsyncIOTransport
+from .rest import BigtableRestTransport
+from .rest import BigtableRestInterceptor
# Compile a registry of transports.
_transport_registry = OrderedDict() # type: Dict[str, Type[BigtableTransport]]
_transport_registry["grpc"] = BigtableGrpcTransport
_transport_registry["grpc_asyncio"] = BigtableGrpcAsyncIOTransport
+_transport_registry["rest"] = BigtableRestTransport
__all__ = (
"BigtableTransport",
"BigtableGrpcTransport",
"BigtableGrpcAsyncIOTransport",
+ "BigtableRestTransport",
+ "BigtableRestInterceptor",
)
diff --git a/google/cloud/bigtable_v2/services/bigtable/transports/base.py b/google/cloud/bigtable_v2/services/bigtable/transports/base.py
index 922068fd0..f08bca73e 100644
--- a/google/cloud/bigtable_v2/services/bigtable/transports/base.py
+++ b/google/cloud/bigtable_v2/services/bigtable/transports/base.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -15,7 +15,8 @@
#
import abc
from typing import Awaitable, Callable, Dict, Optional, Sequence, Union
-import pkg_resources
+
+from google.cloud.bigtable_v2 import gapic_version as package_version
import google.auth # type: ignore
import google.api_core
@@ -24,17 +25,16 @@
from google.api_core import retry as retries
from google.auth import credentials as ga_credentials # type: ignore
from google.oauth2 import service_account # type: ignore
+import google.protobuf
from google.cloud.bigtable_v2.types import bigtable
-try:
- DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
- gapic_version=pkg_resources.get_distribution(
- "google-cloud-bigtable",
- ).version,
- )
-except pkg_resources.DistributionNotFound:
- DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()
+DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
+ gapic_version=package_version.__version__
+)
+
+if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER
+ DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__
class BigtableTransport(abc.ABC):
@@ -55,27 +55,29 @@ def __init__(
self,
*,
host: str = DEFAULT_HOST,
- credentials: ga_credentials.Credentials = None,
+ credentials: Optional[ga_credentials.Credentials] = None,
credentials_file: Optional[str] = None,
scopes: Optional[Sequence[str]] = None,
quota_project_id: Optional[str] = None,
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
always_use_jwt_access: Optional[bool] = False,
+ api_audience: Optional[str] = None,
**kwargs,
) -> None:
"""Instantiate the transport.
Args:
host (Optional[str]):
- The hostname to connect to.
+ The hostname to connect to (default: 'bigtable.googleapis.com').
credentials (Optional[google.auth.credentials.Credentials]): The
authorization credentials to attach to requests. These
credentials identify the application to the service; if none
are specified, the client will attempt to ascertain the
credentials from the environment.
- credentials_file (Optional[str]): A file with credentials that can
+ credentials_file (Optional[str]): Deprecated. A file with credentials that can
be loaded with :func:`google.auth.load_credentials_from_file`.
- This argument is mutually exclusive with credentials.
+ This argument is mutually exclusive with credentials. This argument will be
+ removed in the next major version of this library.
scopes (Optional[Sequence[str]]): A list of scopes.
quota_project_id (Optional[str]): An optional project to use for billing
and quota.
@@ -88,15 +90,12 @@ def __init__(
be used for service account credentials.
"""
- # Save the hostname. Default to port 443 (HTTPS) if none is specified.
- if ":" not in host:
- host += ":443"
- self._host = host
-
scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES}
# Save the scopes.
self._scopes = scopes
+ if not hasattr(self, "_ignore_credentials"):
+ self._ignore_credentials: bool = False
# If no credentials are provided, then determine the appropriate
# defaults.
@@ -109,10 +108,15 @@ def __init__(
credentials, _ = google.auth.load_credentials_from_file(
credentials_file, **scopes_kwargs, quota_project_id=quota_project_id
)
- elif credentials is None:
+ elif credentials is None and not self._ignore_credentials:
credentials, _ = google.auth.default(
**scopes_kwargs, quota_project_id=quota_project_id
)
+ # Don't apply audience if the credentials file passed from user.
+ if hasattr(credentials, "with_gdch_audience"):
+ credentials = credentials.with_gdch_audience(
+ api_audience if api_audience else host
+ )
# If the credentials are service account credentials, then always try to use self signed JWT.
if (
@@ -125,6 +129,15 @@ def __init__(
# Save the credentials.
self._credentials = credentials
+ # Save the hostname. Default to port 443 (HTTPS) if none is specified.
+ if ":" not in host:
+ host += ":443"
+ self._host = host
+
+ @property
+ def host(self):
+ return self._host
+
def _prep_wrapped_messages(self, client_info):
# Precompute the wrapped methods.
self._wrapped_methods = {
@@ -173,6 +186,36 @@ def _prep_wrapped_messages(self, client_info):
default_timeout=20.0,
client_info=client_info,
),
+ self.generate_initial_change_stream_partitions: gapic_v1.method.wrap_method(
+ self.generate_initial_change_stream_partitions,
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.read_change_stream: gapic_v1.method.wrap_method(
+ self.read_change_stream,
+ default_timeout=43200.0,
+ client_info=client_info,
+ ),
+ self.prepare_query: gapic_v1.method.wrap_method(
+ self.prepare_query,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.execute_query: gapic_v1.method.wrap_method(
+ self.execute_query,
+ default_retry=retries.Retry(
+ initial=0.01,
+ maximum=60.0,
+ multiplier=2,
+ predicate=retries.if_exception_type(
+ core_exceptions.DeadlineExceeded,
+ core_exceptions.ServiceUnavailable,
+ ),
+ deadline=43200.0,
+ ),
+ default_timeout=43200.0,
+ client_info=client_info,
+ ),
}
def close(self):
@@ -255,6 +298,48 @@ def read_modify_write_row(
]:
raise NotImplementedError()
+ @property
+ def generate_initial_change_stream_partitions(
+ self,
+ ) -> Callable[
+ [bigtable.GenerateInitialChangeStreamPartitionsRequest],
+ Union[
+ bigtable.GenerateInitialChangeStreamPartitionsResponse,
+ Awaitable[bigtable.GenerateInitialChangeStreamPartitionsResponse],
+ ],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def read_change_stream(
+ self,
+ ) -> Callable[
+ [bigtable.ReadChangeStreamRequest],
+ Union[
+ bigtable.ReadChangeStreamResponse,
+ Awaitable[bigtable.ReadChangeStreamResponse],
+ ],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def prepare_query(
+ self,
+ ) -> Callable[
+ [bigtable.PrepareQueryRequest],
+ Union[bigtable.PrepareQueryResponse, Awaitable[bigtable.PrepareQueryResponse]],
+ ]:
+ raise NotImplementedError()
+
+ @property
+ def execute_query(
+ self,
+ ) -> Callable[
+ [bigtable.ExecuteQueryRequest],
+ Union[bigtable.ExecuteQueryResponse, Awaitable[bigtable.ExecuteQueryResponse]],
+ ]:
+ raise NotImplementedError()
+
@property
def kind(self) -> str:
raise NotImplementedError()
diff --git a/google/cloud/bigtable_v2/services/bigtable/transports/grpc.py b/google/cloud/bigtable_v2/services/bigtable/transports/grpc.py
index ce40cf335..8ddbf15a2 100644
--- a/google/cloud/bigtable_v2/services/bigtable/transports/grpc.py
+++ b/google/cloud/bigtable_v2/services/bigtable/transports/grpc.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -13,6 +13,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+import json
+import logging as std_logging
+import pickle
import warnings
from typing import Callable, Dict, Optional, Sequence, Tuple, Union
@@ -21,12 +24,89 @@
import google.auth # type: ignore
from google.auth import credentials as ga_credentials # type: ignore
from google.auth.transport.grpc import SslCredentials # type: ignore
+from google.protobuf.json_format import MessageToJson
+import google.protobuf.message
import grpc # type: ignore
+import proto # type: ignore
from google.cloud.bigtable_v2.types import bigtable
from .base import BigtableTransport, DEFAULT_CLIENT_INFO
+try:
+ from google.api_core import client_logging # type: ignore
+
+ CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER
+except ImportError: # pragma: NO COVER
+ CLIENT_LOGGING_SUPPORTED = False
+
+_LOGGER = std_logging.getLogger(__name__)
+
+
+class _LoggingClientInterceptor(grpc.UnaryUnaryClientInterceptor): # pragma: NO COVER
+ def intercept_unary_unary(self, continuation, client_call_details, request):
+ logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ std_logging.DEBUG
+ )
+ if logging_enabled: # pragma: NO COVER
+ request_metadata = client_call_details.metadata
+ if isinstance(request, proto.Message):
+ request_payload = type(request).to_json(request)
+ elif isinstance(request, google.protobuf.message.Message):
+ request_payload = MessageToJson(request)
+ else:
+ request_payload = f"{type(request).__name__}: {pickle.dumps(request)}"
+
+ request_metadata = {
+ key: value.decode("utf-8") if isinstance(value, bytes) else value
+ for key, value in request_metadata
+ }
+ grpc_request = {
+ "payload": request_payload,
+ "requestMethod": "grpc",
+ "metadata": dict(request_metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for {client_call_details.method}",
+ extra={
+ "serviceName": "google.bigtable.v2.Bigtable",
+ "rpcName": str(client_call_details.method),
+ "request": grpc_request,
+ "metadata": grpc_request["metadata"],
+ },
+ )
+ response = continuation(client_call_details, request)
+ if logging_enabled: # pragma: NO COVER
+ response_metadata = response.trailing_metadata()
+ # Convert gRPC metadata `` to list of tuples
+ metadata = (
+ dict([(k, str(v)) for k, v in response_metadata])
+ if response_metadata
+ else None
+ )
+ result = response.result()
+ if isinstance(result, proto.Message):
+ response_payload = type(result).to_json(result)
+ elif isinstance(result, google.protobuf.message.Message):
+ response_payload = MessageToJson(result)
+ else:
+ response_payload = f"{type(result).__name__}: {pickle.dumps(result)}"
+ grpc_response = {
+ "payload": response_payload,
+ "metadata": metadata,
+ "status": "OK",
+ }
+ _LOGGER.debug(
+ f"Received response for {client_call_details.method}.",
+ extra={
+ "serviceName": "google.bigtable.v2.Bigtable",
+ "rpcName": client_call_details.method,
+ "response": grpc_response,
+ "metadata": grpc_response["metadata"],
+ },
+ )
+ return response
+
class BigtableGrpcTransport(BigtableTransport):
"""gRPC backend transport for Bigtable.
@@ -48,36 +128,41 @@ def __init__(
self,
*,
host: str = "bigtable.googleapis.com",
- credentials: ga_credentials.Credentials = None,
- credentials_file: str = None,
- scopes: Sequence[str] = None,
- channel: grpc.Channel = None,
- api_mtls_endpoint: str = None,
- client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
- ssl_channel_credentials: grpc.ChannelCredentials = None,
- client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None,
+ credentials: Optional[ga_credentials.Credentials] = None,
+ credentials_file: Optional[str] = None,
+ scopes: Optional[Sequence[str]] = None,
+ channel: Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]] = None,
+ api_mtls_endpoint: Optional[str] = None,
+ client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None,
+ ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None,
+ client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None,
quota_project_id: Optional[str] = None,
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
always_use_jwt_access: Optional[bool] = False,
+ api_audience: Optional[str] = None,
) -> None:
"""Instantiate the transport.
Args:
host (Optional[str]):
- The hostname to connect to.
+ The hostname to connect to (default: 'bigtable.googleapis.com').
credentials (Optional[google.auth.credentials.Credentials]): The
authorization credentials to attach to requests. These
credentials identify the application to the service; if none
are specified, the client will attempt to ascertain the
credentials from the environment.
- This argument is ignored if ``channel`` is provided.
- credentials_file (Optional[str]): A file with credentials that can
+ This argument is ignored if a ``channel`` instance is provided.
+ credentials_file (Optional[str]): Deprecated. A file with credentials that can
be loaded with :func:`google.auth.load_credentials_from_file`.
- This argument is ignored if ``channel`` is provided.
+ This argument is ignored if a ``channel`` instance is provided.
+ This argument will be removed in the next major version of this library.
scopes (Optional(Sequence[str])): A list of scopes. This argument is
- ignored if ``channel`` is provided.
- channel (Optional[grpc.Channel]): A ``Channel`` instance through
- which to make calls.
+ ignored if a ``channel`` instance is provided.
+ channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]):
+ A ``Channel`` instance through which to make calls, or a Callable
+ that constructs and returns one. If set to None, ``self.create_channel``
+ is used to create the channel. If a Callable is given, it will be called
+ with the same arguments as used in ``self.create_channel``.
api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
If provided, it overrides the ``host`` argument and tries to create
a mutual TLS channel with client SSL credentials from
@@ -87,11 +172,11 @@ def __init__(
private key bytes, both in PEM format. It is ignored if
``api_mtls_endpoint`` is None.
ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
- for the grpc channel. It is ignored if ``channel`` is provided.
+ for the grpc channel. It is ignored if a ``channel`` instance is provided.
client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]):
A callback to provide client certificate bytes and private key bytes,
both in PEM format. It is used to configure a mutual TLS channel. It is
- ignored if ``channel`` or ``ssl_channel_credentials`` is provided.
+ ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided.
quota_project_id (Optional[str]): An optional project to use for billing
and quota.
client_info (google.api_core.gapic_v1.client_info.ClientInfo):
@@ -117,9 +202,10 @@ def __init__(
if client_cert_source:
warnings.warn("client_cert_source is deprecated", DeprecationWarning)
- if channel:
+ if isinstance(channel, grpc.Channel):
# Ignore credentials if a channel was passed.
- credentials = False
+ credentials = None
+ self._ignore_credentials = True
# If a channel was explicitly provided, set it.
self._grpc_channel = channel
self._ssl_channel_credentials = None
@@ -154,10 +240,13 @@ def __init__(
quota_project_id=quota_project_id,
client_info=client_info,
always_use_jwt_access=always_use_jwt_access,
+ api_audience=api_audience,
)
if not self._grpc_channel:
- self._grpc_channel = type(self).create_channel(
+ # initialize with the provided callable or the default channel
+ channel_init = channel or type(self).create_channel
+ self._grpc_channel = channel_init(
self._host,
# use the credentials which are saved
credentials=self._credentials,
@@ -173,15 +262,20 @@ def __init__(
],
)
- # Wrap messages. This must be done after self._grpc_channel exists
+ self._interceptor = _LoggingClientInterceptor()
+ self._logged_channel = grpc.intercept_channel(
+ self._grpc_channel, self._interceptor
+ )
+
+ # Wrap messages. This must be done after self._logged_channel exists
self._prep_wrapped_messages(client_info)
@classmethod
def create_channel(
cls,
host: str = "bigtable.googleapis.com",
- credentials: ga_credentials.Credentials = None,
- credentials_file: str = None,
+ credentials: Optional[ga_credentials.Credentials] = None,
+ credentials_file: Optional[str] = None,
scopes: Optional[Sequence[str]] = None,
quota_project_id: Optional[str] = None,
**kwargs,
@@ -194,9 +288,10 @@ def create_channel(
credentials identify this application to the service. If
none are specified, the client will attempt to ascertain
the credentials from the environment.
- credentials_file (Optional[str]): A file with credentials that can
+ credentials_file (Optional[str]): Deprecated. A file with credentials that can
be loaded with :func:`google.auth.load_credentials_from_file`.
- This argument is mutually exclusive with credentials.
+ This argument is mutually exclusive with credentials. This argument will be
+ removed in the next major version of this library.
scopes (Optional[Sequence[str]]): A optional list of scopes needed for this
service. These are only used when credentials are not specified and
are passed to :func:`google.auth.default`.
@@ -252,7 +347,7 @@ def read_rows(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "read_rows" not in self._stubs:
- self._stubs["read_rows"] = self.grpc_channel.unary_stream(
+ self._stubs["read_rows"] = self._logged_channel.unary_stream(
"/google.bigtable.v2.Bigtable/ReadRows",
request_serializer=bigtable.ReadRowsRequest.serialize,
response_deserializer=bigtable.ReadRowsResponse.deserialize,
@@ -282,7 +377,7 @@ def sample_row_keys(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "sample_row_keys" not in self._stubs:
- self._stubs["sample_row_keys"] = self.grpc_channel.unary_stream(
+ self._stubs["sample_row_keys"] = self._logged_channel.unary_stream(
"/google.bigtable.v2.Bigtable/SampleRowKeys",
request_serializer=bigtable.SampleRowKeysRequest.serialize,
response_deserializer=bigtable.SampleRowKeysResponse.deserialize,
@@ -309,7 +404,7 @@ def mutate_row(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "mutate_row" not in self._stubs:
- self._stubs["mutate_row"] = self.grpc_channel.unary_unary(
+ self._stubs["mutate_row"] = self._logged_channel.unary_unary(
"/google.bigtable.v2.Bigtable/MutateRow",
request_serializer=bigtable.MutateRowRequest.serialize,
response_deserializer=bigtable.MutateRowResponse.deserialize,
@@ -337,7 +432,7 @@ def mutate_rows(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "mutate_rows" not in self._stubs:
- self._stubs["mutate_rows"] = self.grpc_channel.unary_stream(
+ self._stubs["mutate_rows"] = self._logged_channel.unary_stream(
"/google.bigtable.v2.Bigtable/MutateRows",
request_serializer=bigtable.MutateRowsRequest.serialize,
response_deserializer=bigtable.MutateRowsResponse.deserialize,
@@ -366,7 +461,7 @@ def check_and_mutate_row(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "check_and_mutate_row" not in self._stubs:
- self._stubs["check_and_mutate_row"] = self.grpc_channel.unary_unary(
+ self._stubs["check_and_mutate_row"] = self._logged_channel.unary_unary(
"/google.bigtable.v2.Bigtable/CheckAndMutateRow",
request_serializer=bigtable.CheckAndMutateRowRequest.serialize,
response_deserializer=bigtable.CheckAndMutateRowResponse.deserialize,
@@ -394,7 +489,7 @@ def ping_and_warm(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "ping_and_warm" not in self._stubs:
- self._stubs["ping_and_warm"] = self.grpc_channel.unary_unary(
+ self._stubs["ping_and_warm"] = self._logged_channel.unary_unary(
"/google.bigtable.v2.Bigtable/PingAndWarm",
request_serializer=bigtable.PingAndWarmRequest.serialize,
response_deserializer=bigtable.PingAndWarmResponse.deserialize,
@@ -428,15 +523,137 @@ def read_modify_write_row(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "read_modify_write_row" not in self._stubs:
- self._stubs["read_modify_write_row"] = self.grpc_channel.unary_unary(
+ self._stubs["read_modify_write_row"] = self._logged_channel.unary_unary(
"/google.bigtable.v2.Bigtable/ReadModifyWriteRow",
request_serializer=bigtable.ReadModifyWriteRowRequest.serialize,
response_deserializer=bigtable.ReadModifyWriteRowResponse.deserialize,
)
return self._stubs["read_modify_write_row"]
+ @property
+ def generate_initial_change_stream_partitions(
+ self,
+ ) -> Callable[
+ [bigtable.GenerateInitialChangeStreamPartitionsRequest],
+ bigtable.GenerateInitialChangeStreamPartitionsResponse,
+ ]:
+ r"""Return a callable for the generate initial change stream
+ partitions method over gRPC.
+
+ Returns the current list of partitions that make up the table's
+ change stream. The union of partitions will cover the entire
+ keyspace. Partitions can be read with ``ReadChangeStream``.
+ NOTE: This API is only intended to be used by Apache Beam
+ BigtableIO.
+
+ Returns:
+ Callable[[~.GenerateInitialChangeStreamPartitionsRequest],
+ ~.GenerateInitialChangeStreamPartitionsResponse]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "generate_initial_change_stream_partitions" not in self._stubs:
+ self._stubs[
+ "generate_initial_change_stream_partitions"
+ ] = self._logged_channel.unary_stream(
+ "/google.bigtable.v2.Bigtable/GenerateInitialChangeStreamPartitions",
+ request_serializer=bigtable.GenerateInitialChangeStreamPartitionsRequest.serialize,
+ response_deserializer=bigtable.GenerateInitialChangeStreamPartitionsResponse.deserialize,
+ )
+ return self._stubs["generate_initial_change_stream_partitions"]
+
+ @property
+ def read_change_stream(
+ self,
+ ) -> Callable[
+ [bigtable.ReadChangeStreamRequest], bigtable.ReadChangeStreamResponse
+ ]:
+ r"""Return a callable for the read change stream method over gRPC.
+
+ Reads changes from a table's change stream. Changes
+ will reflect both user-initiated mutations and mutations
+ that are caused by garbage collection.
+ NOTE: This API is only intended to be used by Apache
+ Beam BigtableIO.
+
+ Returns:
+ Callable[[~.ReadChangeStreamRequest],
+ ~.ReadChangeStreamResponse]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "read_change_stream" not in self._stubs:
+ self._stubs["read_change_stream"] = self._logged_channel.unary_stream(
+ "/google.bigtable.v2.Bigtable/ReadChangeStream",
+ request_serializer=bigtable.ReadChangeStreamRequest.serialize,
+ response_deserializer=bigtable.ReadChangeStreamResponse.deserialize,
+ )
+ return self._stubs["read_change_stream"]
+
+ @property
+ def prepare_query(
+ self,
+ ) -> Callable[[bigtable.PrepareQueryRequest], bigtable.PrepareQueryResponse]:
+ r"""Return a callable for the prepare query method over gRPC.
+
+ Prepares a GoogleSQL query for execution on a
+ particular Bigtable instance.
+
+ Returns:
+ Callable[[~.PrepareQueryRequest],
+ ~.PrepareQueryResponse]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "prepare_query" not in self._stubs:
+ self._stubs["prepare_query"] = self._logged_channel.unary_unary(
+ "/google.bigtable.v2.Bigtable/PrepareQuery",
+ request_serializer=bigtable.PrepareQueryRequest.serialize,
+ response_deserializer=bigtable.PrepareQueryResponse.deserialize,
+ )
+ return self._stubs["prepare_query"]
+
+ @property
+ def execute_query(
+ self,
+ ) -> Callable[[bigtable.ExecuteQueryRequest], bigtable.ExecuteQueryResponse]:
+ r"""Return a callable for the execute query method over gRPC.
+
+ Executes a SQL query against a particular Bigtable
+ instance.
+
+ Returns:
+ Callable[[~.ExecuteQueryRequest],
+ ~.ExecuteQueryResponse]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "execute_query" not in self._stubs:
+ self._stubs["execute_query"] = self._logged_channel.unary_stream(
+ "/google.bigtable.v2.Bigtable/ExecuteQuery",
+ request_serializer=bigtable.ExecuteQueryRequest.serialize,
+ response_deserializer=bigtable.ExecuteQueryResponse.deserialize,
+ )
+ return self._stubs["execute_query"]
+
def close(self):
- self.grpc_channel.close()
+ self._logged_channel.close()
@property
def kind(self) -> str:
diff --git a/google/cloud/bigtable_v2/services/bigtable/transports/grpc_asyncio.py b/google/cloud/bigtable_v2/services/bigtable/transports/grpc_asyncio.py
index 4099e7bd7..3e6b70832 100644
--- a/google/cloud/bigtable_v2/services/bigtable/transports/grpc_asyncio.py
+++ b/google/cloud/bigtable_v2/services/bigtable/transports/grpc_asyncio.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -13,21 +13,106 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+import inspect
+import json
+import pickle
+import logging as std_logging
import warnings
from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union
from google.api_core import gapic_v1
from google.api_core import grpc_helpers_async
+from google.api_core import exceptions as core_exceptions
+from google.api_core import retry_async as retries
from google.auth import credentials as ga_credentials # type: ignore
from google.auth.transport.grpc import SslCredentials # type: ignore
+from google.protobuf.json_format import MessageToJson
+import google.protobuf.message
import grpc # type: ignore
+import proto # type: ignore
from grpc.experimental import aio # type: ignore
from google.cloud.bigtable_v2.types import bigtable
from .base import BigtableTransport, DEFAULT_CLIENT_INFO
from .grpc import BigtableGrpcTransport
+try:
+ from google.api_core import client_logging # type: ignore
+
+ CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER
+except ImportError: # pragma: NO COVER
+ CLIENT_LOGGING_SUPPORTED = False
+
+_LOGGER = std_logging.getLogger(__name__)
+
+
+class _LoggingClientAIOInterceptor(
+ grpc.aio.UnaryUnaryClientInterceptor
+): # pragma: NO COVER
+ async def intercept_unary_unary(self, continuation, client_call_details, request):
+ logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ std_logging.DEBUG
+ )
+ if logging_enabled: # pragma: NO COVER
+ request_metadata = client_call_details.metadata
+ if isinstance(request, proto.Message):
+ request_payload = type(request).to_json(request)
+ elif isinstance(request, google.protobuf.message.Message):
+ request_payload = MessageToJson(request)
+ else:
+ request_payload = f"{type(request).__name__}: {pickle.dumps(request)}"
+
+ request_metadata = {
+ key: value.decode("utf-8") if isinstance(value, bytes) else value
+ for key, value in request_metadata
+ }
+ grpc_request = {
+ "payload": request_payload,
+ "requestMethod": "grpc",
+ "metadata": dict(request_metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for {client_call_details.method}",
+ extra={
+ "serviceName": "google.bigtable.v2.Bigtable",
+ "rpcName": str(client_call_details.method),
+ "request": grpc_request,
+ "metadata": grpc_request["metadata"],
+ },
+ )
+ response = await continuation(client_call_details, request)
+ if logging_enabled: # pragma: NO COVER
+ response_metadata = await response.trailing_metadata()
+ # Convert gRPC metadata `` to list of tuples
+ metadata = (
+ dict([(k, str(v)) for k, v in response_metadata])
+ if response_metadata
+ else None
+ )
+ result = await response
+ if isinstance(result, proto.Message):
+ response_payload = type(result).to_json(result)
+ elif isinstance(result, google.protobuf.message.Message):
+ response_payload = MessageToJson(result)
+ else:
+ response_payload = f"{type(result).__name__}: {pickle.dumps(result)}"
+ grpc_response = {
+ "payload": response_payload,
+ "metadata": metadata,
+ "status": "OK",
+ }
+ _LOGGER.debug(
+ f"Received response to rpc {client_call_details.method}.",
+ extra={
+ "serviceName": "google.bigtable.v2.Bigtable",
+ "rpcName": str(client_call_details.method),
+ "response": grpc_response,
+ "metadata": grpc_response["metadata"],
+ },
+ )
+ return response
+
class BigtableGrpcAsyncIOTransport(BigtableTransport):
"""gRPC AsyncIO backend transport for Bigtable.
@@ -50,7 +135,7 @@ class BigtableGrpcAsyncIOTransport(BigtableTransport):
def create_channel(
cls,
host: str = "bigtable.googleapis.com",
- credentials: ga_credentials.Credentials = None,
+ credentials: Optional[ga_credentials.Credentials] = None,
credentials_file: Optional[str] = None,
scopes: Optional[Sequence[str]] = None,
quota_project_id: Optional[str] = None,
@@ -64,9 +149,9 @@ def create_channel(
credentials identify this application to the service. If
none are specified, the client will attempt to ascertain
the credentials from the environment.
- credentials_file (Optional[str]): A file with credentials that can
- be loaded with :func:`google.auth.load_credentials_from_file`.
- This argument is ignored if ``channel`` is provided.
+ credentials_file (Optional[str]): Deprecated. A file with credentials that can
+ be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be
+ removed in the next major version of this library.
scopes (Optional[Sequence[str]]): A optional list of scopes needed for this
service. These are only used when credentials are not specified and
are passed to :func:`google.auth.default`.
@@ -93,37 +178,42 @@ def __init__(
self,
*,
host: str = "bigtable.googleapis.com",
- credentials: ga_credentials.Credentials = None,
+ credentials: Optional[ga_credentials.Credentials] = None,
credentials_file: Optional[str] = None,
scopes: Optional[Sequence[str]] = None,
- channel: aio.Channel = None,
- api_mtls_endpoint: str = None,
- client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
- ssl_channel_credentials: grpc.ChannelCredentials = None,
- client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None,
- quota_project_id=None,
+ channel: Optional[Union[aio.Channel, Callable[..., aio.Channel]]] = None,
+ api_mtls_endpoint: Optional[str] = None,
+ client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None,
+ ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None,
+ client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None,
+ quota_project_id: Optional[str] = None,
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
always_use_jwt_access: Optional[bool] = False,
+ api_audience: Optional[str] = None,
) -> None:
"""Instantiate the transport.
Args:
host (Optional[str]):
- The hostname to connect to.
+ The hostname to connect to (default: 'bigtable.googleapis.com').
credentials (Optional[google.auth.credentials.Credentials]): The
authorization credentials to attach to requests. These
credentials identify the application to the service; if none
are specified, the client will attempt to ascertain the
credentials from the environment.
- This argument is ignored if ``channel`` is provided.
- credentials_file (Optional[str]): A file with credentials that can
+ This argument is ignored if a ``channel`` instance is provided.
+ credentials_file (Optional[str]): Deprecated. A file with credentials that can
be loaded with :func:`google.auth.load_credentials_from_file`.
- This argument is ignored if ``channel`` is provided.
+ This argument is ignored if a ``channel`` instance is provided.
+ This argument will be removed in the next major version of this library.
scopes (Optional[Sequence[str]]): A optional list of scopes needed for this
service. These are only used when credentials are not specified and
are passed to :func:`google.auth.default`.
- channel (Optional[aio.Channel]): A ``Channel`` instance through
- which to make calls.
+ channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]):
+ A ``Channel`` instance through which to make calls, or a Callable
+ that constructs and returns one. If set to None, ``self.create_channel``
+ is used to create the channel. If a Callable is given, it will be called
+ with the same arguments as used in ``self.create_channel``.
api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
If provided, it overrides the ``host`` argument and tries to create
a mutual TLS channel with client SSL credentials from
@@ -133,11 +223,11 @@ def __init__(
private key bytes, both in PEM format. It is ignored if
``api_mtls_endpoint`` is None.
ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
- for the grpc channel. It is ignored if ``channel`` is provided.
+ for the grpc channel. It is ignored if a ``channel`` instance is provided.
client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]):
A callback to provide client certificate bytes and private key bytes,
both in PEM format. It is used to configure a mutual TLS channel. It is
- ignored if ``channel`` or ``ssl_channel_credentials`` is provided.
+ ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided.
quota_project_id (Optional[str]): An optional project to use for billing
and quota.
client_info (google.api_core.gapic_v1.client_info.ClientInfo):
@@ -163,9 +253,10 @@ def __init__(
if client_cert_source:
warnings.warn("client_cert_source is deprecated", DeprecationWarning)
- if channel:
+ if isinstance(channel, aio.Channel):
# Ignore credentials if a channel was passed.
- credentials = False
+ credentials = None
+ self._ignore_credentials = True
# If a channel was explicitly provided, set it.
self._grpc_channel = channel
self._ssl_channel_credentials = None
@@ -199,10 +290,13 @@ def __init__(
quota_project_id=quota_project_id,
client_info=client_info,
always_use_jwt_access=always_use_jwt_access,
+ api_audience=api_audience,
)
if not self._grpc_channel:
- self._grpc_channel = type(self).create_channel(
+ # initialize with the provided callable or the default channel
+ channel_init = channel or type(self).create_channel
+ self._grpc_channel = channel_init(
self._host,
# use the credentials which are saved
credentials=self._credentials,
@@ -218,7 +312,13 @@ def __init__(
],
)
- # Wrap messages. This must be done after self._grpc_channel exists
+ self._interceptor = _LoggingClientAIOInterceptor()
+ self._grpc_channel._unary_unary_interceptors.append(self._interceptor)
+ self._logged_channel = self._grpc_channel
+ self._wrap_with_kind = (
+ "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters
+ )
+ # Wrap messages. This must be done after self._logged_channel exists
self._prep_wrapped_messages(client_info)
@property
@@ -255,7 +355,7 @@ def read_rows(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "read_rows" not in self._stubs:
- self._stubs["read_rows"] = self.grpc_channel.unary_stream(
+ self._stubs["read_rows"] = self._logged_channel.unary_stream(
"/google.bigtable.v2.Bigtable/ReadRows",
request_serializer=bigtable.ReadRowsRequest.serialize,
response_deserializer=bigtable.ReadRowsResponse.deserialize,
@@ -287,7 +387,7 @@ def sample_row_keys(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "sample_row_keys" not in self._stubs:
- self._stubs["sample_row_keys"] = self.grpc_channel.unary_stream(
+ self._stubs["sample_row_keys"] = self._logged_channel.unary_stream(
"/google.bigtable.v2.Bigtable/SampleRowKeys",
request_serializer=bigtable.SampleRowKeysRequest.serialize,
response_deserializer=bigtable.SampleRowKeysResponse.deserialize,
@@ -314,7 +414,7 @@ def mutate_row(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "mutate_row" not in self._stubs:
- self._stubs["mutate_row"] = self.grpc_channel.unary_unary(
+ self._stubs["mutate_row"] = self._logged_channel.unary_unary(
"/google.bigtable.v2.Bigtable/MutateRow",
request_serializer=bigtable.MutateRowRequest.serialize,
response_deserializer=bigtable.MutateRowResponse.deserialize,
@@ -342,7 +442,7 @@ def mutate_rows(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "mutate_rows" not in self._stubs:
- self._stubs["mutate_rows"] = self.grpc_channel.unary_stream(
+ self._stubs["mutate_rows"] = self._logged_channel.unary_stream(
"/google.bigtable.v2.Bigtable/MutateRows",
request_serializer=bigtable.MutateRowsRequest.serialize,
response_deserializer=bigtable.MutateRowsResponse.deserialize,
@@ -372,7 +472,7 @@ def check_and_mutate_row(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "check_and_mutate_row" not in self._stubs:
- self._stubs["check_and_mutate_row"] = self.grpc_channel.unary_unary(
+ self._stubs["check_and_mutate_row"] = self._logged_channel.unary_unary(
"/google.bigtable.v2.Bigtable/CheckAndMutateRow",
request_serializer=bigtable.CheckAndMutateRowRequest.serialize,
response_deserializer=bigtable.CheckAndMutateRowResponse.deserialize,
@@ -402,7 +502,7 @@ def ping_and_warm(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "ping_and_warm" not in self._stubs:
- self._stubs["ping_and_warm"] = self.grpc_channel.unary_unary(
+ self._stubs["ping_and_warm"] = self._logged_channel.unary_unary(
"/google.bigtable.v2.Bigtable/PingAndWarm",
request_serializer=bigtable.PingAndWarmRequest.serialize,
response_deserializer=bigtable.PingAndWarmResponse.deserialize,
@@ -437,15 +537,230 @@ def read_modify_write_row(
# gRPC handles serialization and deserialization, so we just need
# to pass in the functions for each.
if "read_modify_write_row" not in self._stubs:
- self._stubs["read_modify_write_row"] = self.grpc_channel.unary_unary(
+ self._stubs["read_modify_write_row"] = self._logged_channel.unary_unary(
"/google.bigtable.v2.Bigtable/ReadModifyWriteRow",
request_serializer=bigtable.ReadModifyWriteRowRequest.serialize,
response_deserializer=bigtable.ReadModifyWriteRowResponse.deserialize,
)
return self._stubs["read_modify_write_row"]
+ @property
+ def generate_initial_change_stream_partitions(
+ self,
+ ) -> Callable[
+ [bigtable.GenerateInitialChangeStreamPartitionsRequest],
+ Awaitable[bigtable.GenerateInitialChangeStreamPartitionsResponse],
+ ]:
+ r"""Return a callable for the generate initial change stream
+ partitions method over gRPC.
+
+ Returns the current list of partitions that make up the table's
+ change stream. The union of partitions will cover the entire
+ keyspace. Partitions can be read with ``ReadChangeStream``.
+ NOTE: This API is only intended to be used by Apache Beam
+ BigtableIO.
+
+ Returns:
+ Callable[[~.GenerateInitialChangeStreamPartitionsRequest],
+ Awaitable[~.GenerateInitialChangeStreamPartitionsResponse]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "generate_initial_change_stream_partitions" not in self._stubs:
+ self._stubs[
+ "generate_initial_change_stream_partitions"
+ ] = self._logged_channel.unary_stream(
+ "/google.bigtable.v2.Bigtable/GenerateInitialChangeStreamPartitions",
+ request_serializer=bigtable.GenerateInitialChangeStreamPartitionsRequest.serialize,
+ response_deserializer=bigtable.GenerateInitialChangeStreamPartitionsResponse.deserialize,
+ )
+ return self._stubs["generate_initial_change_stream_partitions"]
+
+ @property
+ def read_change_stream(
+ self,
+ ) -> Callable[
+ [bigtable.ReadChangeStreamRequest], Awaitable[bigtable.ReadChangeStreamResponse]
+ ]:
+ r"""Return a callable for the read change stream method over gRPC.
+
+ Reads changes from a table's change stream. Changes
+ will reflect both user-initiated mutations and mutations
+ that are caused by garbage collection.
+ NOTE: This API is only intended to be used by Apache
+ Beam BigtableIO.
+
+ Returns:
+ Callable[[~.ReadChangeStreamRequest],
+ Awaitable[~.ReadChangeStreamResponse]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "read_change_stream" not in self._stubs:
+ self._stubs["read_change_stream"] = self._logged_channel.unary_stream(
+ "/google.bigtable.v2.Bigtable/ReadChangeStream",
+ request_serializer=bigtable.ReadChangeStreamRequest.serialize,
+ response_deserializer=bigtable.ReadChangeStreamResponse.deserialize,
+ )
+ return self._stubs["read_change_stream"]
+
+ @property
+ def prepare_query(
+ self,
+ ) -> Callable[
+ [bigtable.PrepareQueryRequest], Awaitable[bigtable.PrepareQueryResponse]
+ ]:
+ r"""Return a callable for the prepare query method over gRPC.
+
+ Prepares a GoogleSQL query for execution on a
+ particular Bigtable instance.
+
+ Returns:
+ Callable[[~.PrepareQueryRequest],
+ Awaitable[~.PrepareQueryResponse]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "prepare_query" not in self._stubs:
+ self._stubs["prepare_query"] = self._logged_channel.unary_unary(
+ "/google.bigtable.v2.Bigtable/PrepareQuery",
+ request_serializer=bigtable.PrepareQueryRequest.serialize,
+ response_deserializer=bigtable.PrepareQueryResponse.deserialize,
+ )
+ return self._stubs["prepare_query"]
+
+ @property
+ def execute_query(
+ self,
+ ) -> Callable[
+ [bigtable.ExecuteQueryRequest], Awaitable[bigtable.ExecuteQueryResponse]
+ ]:
+ r"""Return a callable for the execute query method over gRPC.
+
+ Executes a SQL query against a particular Bigtable
+ instance.
+
+ Returns:
+ Callable[[~.ExecuteQueryRequest],
+ Awaitable[~.ExecuteQueryResponse]]:
+ A function that, when called, will call the underlying RPC
+ on the server.
+ """
+ # Generate a "stub function" on-the-fly which will actually make
+ # the request.
+ # gRPC handles serialization and deserialization, so we just need
+ # to pass in the functions for each.
+ if "execute_query" not in self._stubs:
+ self._stubs["execute_query"] = self._logged_channel.unary_stream(
+ "/google.bigtable.v2.Bigtable/ExecuteQuery",
+ request_serializer=bigtable.ExecuteQueryRequest.serialize,
+ response_deserializer=bigtable.ExecuteQueryResponse.deserialize,
+ )
+ return self._stubs["execute_query"]
+
+ def _prep_wrapped_messages(self, client_info):
+ """Precompute the wrapped methods, overriding the base class method to use async wrappers."""
+ self._wrapped_methods = {
+ self.read_rows: self._wrap_method(
+ self.read_rows,
+ default_timeout=43200.0,
+ client_info=client_info,
+ ),
+ self.sample_row_keys: self._wrap_method(
+ self.sample_row_keys,
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.mutate_row: self._wrap_method(
+ self.mutate_row,
+ default_retry=retries.AsyncRetry(
+ initial=0.01,
+ maximum=60.0,
+ multiplier=2,
+ predicate=retries.if_exception_type(
+ core_exceptions.DeadlineExceeded,
+ core_exceptions.ServiceUnavailable,
+ ),
+ deadline=60.0,
+ ),
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.mutate_rows: self._wrap_method(
+ self.mutate_rows,
+ default_timeout=600.0,
+ client_info=client_info,
+ ),
+ self.check_and_mutate_row: self._wrap_method(
+ self.check_and_mutate_row,
+ default_timeout=20.0,
+ client_info=client_info,
+ ),
+ self.ping_and_warm: self._wrap_method(
+ self.ping_and_warm,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.read_modify_write_row: self._wrap_method(
+ self.read_modify_write_row,
+ default_timeout=20.0,
+ client_info=client_info,
+ ),
+ self.generate_initial_change_stream_partitions: self._wrap_method(
+ self.generate_initial_change_stream_partitions,
+ default_timeout=60.0,
+ client_info=client_info,
+ ),
+ self.read_change_stream: self._wrap_method(
+ self.read_change_stream,
+ default_timeout=43200.0,
+ client_info=client_info,
+ ),
+ self.prepare_query: self._wrap_method(
+ self.prepare_query,
+ default_timeout=None,
+ client_info=client_info,
+ ),
+ self.execute_query: self._wrap_method(
+ self.execute_query,
+ default_retry=retries.AsyncRetry(
+ initial=0.01,
+ maximum=60.0,
+ multiplier=2,
+ predicate=retries.if_exception_type(
+ core_exceptions.DeadlineExceeded,
+ core_exceptions.ServiceUnavailable,
+ ),
+ deadline=43200.0,
+ ),
+ default_timeout=43200.0,
+ client_info=client_info,
+ ),
+ }
+
+ def _wrap_method(self, func, *args, **kwargs):
+ if self._wrap_with_kind: # pragma: NO COVER
+ kwargs["kind"] = self.kind
+ return gapic_v1.method_async.wrap_method(func, *args, **kwargs)
+
def close(self):
- return self.grpc_channel.close()
+ return self._logged_channel.close()
+
+ @property
+ def kind(self) -> str:
+ return "grpc_asyncio"
__all__ = ("BigtableGrpcAsyncIOTransport",)
diff --git a/google/cloud/bigtable_v2/services/bigtable/transports/rest.py b/google/cloud/bigtable_v2/services/bigtable/transports/rest.py
new file mode 100644
index 000000000..f0a761a36
--- /dev/null
+++ b/google/cloud/bigtable_v2/services/bigtable/transports/rest.py
@@ -0,0 +1,2590 @@
+# -*- coding: utf-8 -*-
+# Copyright 2025 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 logging
+import json # type: ignore
+
+from google.auth.transport.requests import AuthorizedSession # type: ignore
+from google.auth import credentials as ga_credentials # type: ignore
+from google.api_core import exceptions as core_exceptions
+from google.api_core import retry as retries
+from google.api_core import rest_helpers
+from google.api_core import rest_streaming
+from google.api_core import gapic_v1
+import google.protobuf
+
+from google.protobuf import json_format
+
+from requests import __version__ as requests_version
+import dataclasses
+from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union
+import warnings
+
+
+from google.cloud.bigtable_v2.types import bigtable
+
+
+from .rest_base import _BaseBigtableRestTransport
+from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO
+
+try:
+ OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None]
+except AttributeError: # pragma: NO COVER
+ OptionalRetry = Union[retries.Retry, object, None] # type: ignore
+
+try:
+ from google.api_core import client_logging # type: ignore
+
+ CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER
+except ImportError: # pragma: NO COVER
+ CLIENT_LOGGING_SUPPORTED = False
+
+_LOGGER = logging.getLogger(__name__)
+
+DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
+ gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version,
+ grpc_version=None,
+ rest_version=f"requests@{requests_version}",
+)
+
+if hasattr(DEFAULT_CLIENT_INFO, "protobuf_runtime_version"): # pragma: NO COVER
+ DEFAULT_CLIENT_INFO.protobuf_runtime_version = google.protobuf.__version__
+
+
+class BigtableRestInterceptor:
+ """Interceptor for Bigtable.
+
+ Interceptors are used to manipulate requests, request metadata, and responses
+ in arbitrary ways.
+ Example use cases include:
+ * Logging
+ * Verifying requests according to service or custom semantics
+ * Stripping extraneous information from responses
+
+ These use cases and more can be enabled by injecting an
+ instance of a custom subclass when constructing the BigtableRestTransport.
+
+ .. code-block:: python
+ class MyCustomBigtableInterceptor(BigtableRestInterceptor):
+ def pre_check_and_mutate_row(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_check_and_mutate_row(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_execute_query(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_execute_query(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_generate_initial_change_stream_partitions(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_generate_initial_change_stream_partitions(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_mutate_row(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_mutate_row(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_mutate_rows(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_mutate_rows(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_ping_and_warm(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_ping_and_warm(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_prepare_query(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_prepare_query(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_read_change_stream(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_read_change_stream(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_read_modify_write_row(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_read_modify_write_row(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_read_rows(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_read_rows(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ def pre_sample_row_keys(self, request, metadata):
+ logging.log(f"Received request: {request}")
+ return request, metadata
+
+ def post_sample_row_keys(self, response):
+ logging.log(f"Received response: {response}")
+ return response
+
+ transport = BigtableRestTransport(interceptor=MyCustomBigtableInterceptor())
+ client = BigtableClient(transport=transport)
+
+
+ """
+
+ def pre_check_and_mutate_row(
+ self,
+ request: bigtable.CheckAndMutateRowRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable.CheckAndMutateRowRequest, Sequence[Tuple[str, Union[str, bytes]]]
+ ]:
+ """Pre-rpc interceptor for check_and_mutate_row
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the Bigtable server.
+ """
+ return request, metadata
+
+ def post_check_and_mutate_row(
+ self, response: bigtable.CheckAndMutateRowResponse
+ ) -> bigtable.CheckAndMutateRowResponse:
+ """Post-rpc interceptor for check_and_mutate_row
+
+ DEPRECATED. Please use the `post_check_and_mutate_row_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the Bigtable server but before
+ it is returned to user code. This `post_check_and_mutate_row` interceptor runs
+ before the `post_check_and_mutate_row_with_metadata` interceptor.
+ """
+ return response
+
+ def post_check_and_mutate_row_with_metadata(
+ self,
+ response: bigtable.CheckAndMutateRowResponse,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable.CheckAndMutateRowResponse, Sequence[Tuple[str, Union[str, bytes]]]
+ ]:
+ """Post-rpc interceptor for check_and_mutate_row
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the Bigtable server but before it is returned to user code.
+
+ We recommend only using this `post_check_and_mutate_row_with_metadata`
+ interceptor in new development instead of the `post_check_and_mutate_row` interceptor.
+ When both interceptors are used, this `post_check_and_mutate_row_with_metadata` interceptor runs after the
+ `post_check_and_mutate_row` interceptor. The (possibly modified) response returned by
+ `post_check_and_mutate_row` will be passed to
+ `post_check_and_mutate_row_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_execute_query(
+ self,
+ request: bigtable.ExecuteQueryRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[bigtable.ExecuteQueryRequest, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Pre-rpc interceptor for execute_query
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the Bigtable server.
+ """
+ return request, metadata
+
+ def post_execute_query(
+ self, response: rest_streaming.ResponseIterator
+ ) -> rest_streaming.ResponseIterator:
+ """Post-rpc interceptor for execute_query
+
+ DEPRECATED. Please use the `post_execute_query_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the Bigtable server but before
+ it is returned to user code. This `post_execute_query` interceptor runs
+ before the `post_execute_query_with_metadata` interceptor.
+ """
+ return response
+
+ def post_execute_query_with_metadata(
+ self,
+ response: rest_streaming.ResponseIterator,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ rest_streaming.ResponseIterator, Sequence[Tuple[str, Union[str, bytes]]]
+ ]:
+ """Post-rpc interceptor for execute_query
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the Bigtable server but before it is returned to user code.
+
+ We recommend only using this `post_execute_query_with_metadata`
+ interceptor in new development instead of the `post_execute_query` interceptor.
+ When both interceptors are used, this `post_execute_query_with_metadata` interceptor runs after the
+ `post_execute_query` interceptor. The (possibly modified) response returned by
+ `post_execute_query` will be passed to
+ `post_execute_query_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_generate_initial_change_stream_partitions(
+ self,
+ request: bigtable.GenerateInitialChangeStreamPartitionsRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable.GenerateInitialChangeStreamPartitionsRequest,
+ Sequence[Tuple[str, Union[str, bytes]]],
+ ]:
+ """Pre-rpc interceptor for generate_initial_change_stream_partitions
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the Bigtable server.
+ """
+ return request, metadata
+
+ def post_generate_initial_change_stream_partitions(
+ self, response: rest_streaming.ResponseIterator
+ ) -> rest_streaming.ResponseIterator:
+ """Post-rpc interceptor for generate_initial_change_stream_partitions
+
+ DEPRECATED. Please use the `post_generate_initial_change_stream_partitions_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the Bigtable server but before
+ it is returned to user code. This `post_generate_initial_change_stream_partitions` interceptor runs
+ before the `post_generate_initial_change_stream_partitions_with_metadata` interceptor.
+ """
+ return response
+
+ def post_generate_initial_change_stream_partitions_with_metadata(
+ self,
+ response: rest_streaming.ResponseIterator,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ rest_streaming.ResponseIterator, Sequence[Tuple[str, Union[str, bytes]]]
+ ]:
+ """Post-rpc interceptor for generate_initial_change_stream_partitions
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the Bigtable server but before it is returned to user code.
+
+ We recommend only using this `post_generate_initial_change_stream_partitions_with_metadata`
+ interceptor in new development instead of the `post_generate_initial_change_stream_partitions` interceptor.
+ When both interceptors are used, this `post_generate_initial_change_stream_partitions_with_metadata` interceptor runs after the
+ `post_generate_initial_change_stream_partitions` interceptor. The (possibly modified) response returned by
+ `post_generate_initial_change_stream_partitions` will be passed to
+ `post_generate_initial_change_stream_partitions_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_mutate_row(
+ self,
+ request: bigtable.MutateRowRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[bigtable.MutateRowRequest, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Pre-rpc interceptor for mutate_row
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the Bigtable server.
+ """
+ return request, metadata
+
+ def post_mutate_row(
+ self, response: bigtable.MutateRowResponse
+ ) -> bigtable.MutateRowResponse:
+ """Post-rpc interceptor for mutate_row
+
+ DEPRECATED. Please use the `post_mutate_row_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the Bigtable server but before
+ it is returned to user code. This `post_mutate_row` interceptor runs
+ before the `post_mutate_row_with_metadata` interceptor.
+ """
+ return response
+
+ def post_mutate_row_with_metadata(
+ self,
+ response: bigtable.MutateRowResponse,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[bigtable.MutateRowResponse, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for mutate_row
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the Bigtable server but before it is returned to user code.
+
+ We recommend only using this `post_mutate_row_with_metadata`
+ interceptor in new development instead of the `post_mutate_row` interceptor.
+ When both interceptors are used, this `post_mutate_row_with_metadata` interceptor runs after the
+ `post_mutate_row` interceptor. The (possibly modified) response returned by
+ `post_mutate_row` will be passed to
+ `post_mutate_row_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_mutate_rows(
+ self,
+ request: bigtable.MutateRowsRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[bigtable.MutateRowsRequest, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Pre-rpc interceptor for mutate_rows
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the Bigtable server.
+ """
+ return request, metadata
+
+ def post_mutate_rows(
+ self, response: rest_streaming.ResponseIterator
+ ) -> rest_streaming.ResponseIterator:
+ """Post-rpc interceptor for mutate_rows
+
+ DEPRECATED. Please use the `post_mutate_rows_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the Bigtable server but before
+ it is returned to user code. This `post_mutate_rows` interceptor runs
+ before the `post_mutate_rows_with_metadata` interceptor.
+ """
+ return response
+
+ def post_mutate_rows_with_metadata(
+ self,
+ response: rest_streaming.ResponseIterator,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ rest_streaming.ResponseIterator, Sequence[Tuple[str, Union[str, bytes]]]
+ ]:
+ """Post-rpc interceptor for mutate_rows
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the Bigtable server but before it is returned to user code.
+
+ We recommend only using this `post_mutate_rows_with_metadata`
+ interceptor in new development instead of the `post_mutate_rows` interceptor.
+ When both interceptors are used, this `post_mutate_rows_with_metadata` interceptor runs after the
+ `post_mutate_rows` interceptor. The (possibly modified) response returned by
+ `post_mutate_rows` will be passed to
+ `post_mutate_rows_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_ping_and_warm(
+ self,
+ request: bigtable.PingAndWarmRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[bigtable.PingAndWarmRequest, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Pre-rpc interceptor for ping_and_warm
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the Bigtable server.
+ """
+ return request, metadata
+
+ def post_ping_and_warm(
+ self, response: bigtable.PingAndWarmResponse
+ ) -> bigtable.PingAndWarmResponse:
+ """Post-rpc interceptor for ping_and_warm
+
+ DEPRECATED. Please use the `post_ping_and_warm_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the Bigtable server but before
+ it is returned to user code. This `post_ping_and_warm` interceptor runs
+ before the `post_ping_and_warm_with_metadata` interceptor.
+ """
+ return response
+
+ def post_ping_and_warm_with_metadata(
+ self,
+ response: bigtable.PingAndWarmResponse,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[bigtable.PingAndWarmResponse, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for ping_and_warm
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the Bigtable server but before it is returned to user code.
+
+ We recommend only using this `post_ping_and_warm_with_metadata`
+ interceptor in new development instead of the `post_ping_and_warm` interceptor.
+ When both interceptors are used, this `post_ping_and_warm_with_metadata` interceptor runs after the
+ `post_ping_and_warm` interceptor. The (possibly modified) response returned by
+ `post_ping_and_warm` will be passed to
+ `post_ping_and_warm_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_prepare_query(
+ self,
+ request: bigtable.PrepareQueryRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[bigtable.PrepareQueryRequest, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Pre-rpc interceptor for prepare_query
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the Bigtable server.
+ """
+ return request, metadata
+
+ def post_prepare_query(
+ self, response: bigtable.PrepareQueryResponse
+ ) -> bigtable.PrepareQueryResponse:
+ """Post-rpc interceptor for prepare_query
+
+ DEPRECATED. Please use the `post_prepare_query_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the Bigtable server but before
+ it is returned to user code. This `post_prepare_query` interceptor runs
+ before the `post_prepare_query_with_metadata` interceptor.
+ """
+ return response
+
+ def post_prepare_query_with_metadata(
+ self,
+ response: bigtable.PrepareQueryResponse,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[bigtable.PrepareQueryResponse, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Post-rpc interceptor for prepare_query
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the Bigtable server but before it is returned to user code.
+
+ We recommend only using this `post_prepare_query_with_metadata`
+ interceptor in new development instead of the `post_prepare_query` interceptor.
+ When both interceptors are used, this `post_prepare_query_with_metadata` interceptor runs after the
+ `post_prepare_query` interceptor. The (possibly modified) response returned by
+ `post_prepare_query` will be passed to
+ `post_prepare_query_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_read_change_stream(
+ self,
+ request: bigtable.ReadChangeStreamRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable.ReadChangeStreamRequest, Sequence[Tuple[str, Union[str, bytes]]]
+ ]:
+ """Pre-rpc interceptor for read_change_stream
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the Bigtable server.
+ """
+ return request, metadata
+
+ def post_read_change_stream(
+ self, response: rest_streaming.ResponseIterator
+ ) -> rest_streaming.ResponseIterator:
+ """Post-rpc interceptor for read_change_stream
+
+ DEPRECATED. Please use the `post_read_change_stream_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the Bigtable server but before
+ it is returned to user code. This `post_read_change_stream` interceptor runs
+ before the `post_read_change_stream_with_metadata` interceptor.
+ """
+ return response
+
+ def post_read_change_stream_with_metadata(
+ self,
+ response: rest_streaming.ResponseIterator,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ rest_streaming.ResponseIterator, Sequence[Tuple[str, Union[str, bytes]]]
+ ]:
+ """Post-rpc interceptor for read_change_stream
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the Bigtable server but before it is returned to user code.
+
+ We recommend only using this `post_read_change_stream_with_metadata`
+ interceptor in new development instead of the `post_read_change_stream` interceptor.
+ When both interceptors are used, this `post_read_change_stream_with_metadata` interceptor runs after the
+ `post_read_change_stream` interceptor. The (possibly modified) response returned by
+ `post_read_change_stream` will be passed to
+ `post_read_change_stream_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_read_modify_write_row(
+ self,
+ request: bigtable.ReadModifyWriteRowRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable.ReadModifyWriteRowRequest, Sequence[Tuple[str, Union[str, bytes]]]
+ ]:
+ """Pre-rpc interceptor for read_modify_write_row
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the Bigtable server.
+ """
+ return request, metadata
+
+ def post_read_modify_write_row(
+ self, response: bigtable.ReadModifyWriteRowResponse
+ ) -> bigtable.ReadModifyWriteRowResponse:
+ """Post-rpc interceptor for read_modify_write_row
+
+ DEPRECATED. Please use the `post_read_modify_write_row_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the Bigtable server but before
+ it is returned to user code. This `post_read_modify_write_row` interceptor runs
+ before the `post_read_modify_write_row_with_metadata` interceptor.
+ """
+ return response
+
+ def post_read_modify_write_row_with_metadata(
+ self,
+ response: bigtable.ReadModifyWriteRowResponse,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ bigtable.ReadModifyWriteRowResponse, Sequence[Tuple[str, Union[str, bytes]]]
+ ]:
+ """Post-rpc interceptor for read_modify_write_row
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the Bigtable server but before it is returned to user code.
+
+ We recommend only using this `post_read_modify_write_row_with_metadata`
+ interceptor in new development instead of the `post_read_modify_write_row` interceptor.
+ When both interceptors are used, this `post_read_modify_write_row_with_metadata` interceptor runs after the
+ `post_read_modify_write_row` interceptor. The (possibly modified) response returned by
+ `post_read_modify_write_row` will be passed to
+ `post_read_modify_write_row_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_read_rows(
+ self,
+ request: bigtable.ReadRowsRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[bigtable.ReadRowsRequest, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Pre-rpc interceptor for read_rows
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the Bigtable server.
+ """
+ return request, metadata
+
+ def post_read_rows(
+ self, response: rest_streaming.ResponseIterator
+ ) -> rest_streaming.ResponseIterator:
+ """Post-rpc interceptor for read_rows
+
+ DEPRECATED. Please use the `post_read_rows_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the Bigtable server but before
+ it is returned to user code. This `post_read_rows` interceptor runs
+ before the `post_read_rows_with_metadata` interceptor.
+ """
+ return response
+
+ def post_read_rows_with_metadata(
+ self,
+ response: rest_streaming.ResponseIterator,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ rest_streaming.ResponseIterator, Sequence[Tuple[str, Union[str, bytes]]]
+ ]:
+ """Post-rpc interceptor for read_rows
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the Bigtable server but before it is returned to user code.
+
+ We recommend only using this `post_read_rows_with_metadata`
+ interceptor in new development instead of the `post_read_rows` interceptor.
+ When both interceptors are used, this `post_read_rows_with_metadata` interceptor runs after the
+ `post_read_rows` interceptor. The (possibly modified) response returned by
+ `post_read_rows` will be passed to
+ `post_read_rows_with_metadata`.
+ """
+ return response, metadata
+
+ def pre_sample_row_keys(
+ self,
+ request: bigtable.SampleRowKeysRequest,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[bigtable.SampleRowKeysRequest, Sequence[Tuple[str, Union[str, bytes]]]]:
+ """Pre-rpc interceptor for sample_row_keys
+
+ Override in a subclass to manipulate the request or metadata
+ before they are sent to the Bigtable server.
+ """
+ return request, metadata
+
+ def post_sample_row_keys(
+ self, response: rest_streaming.ResponseIterator
+ ) -> rest_streaming.ResponseIterator:
+ """Post-rpc interceptor for sample_row_keys
+
+ DEPRECATED. Please use the `post_sample_row_keys_with_metadata`
+ interceptor instead.
+
+ Override in a subclass to read or manipulate the response
+ after it is returned by the Bigtable server but before
+ it is returned to user code. This `post_sample_row_keys` interceptor runs
+ before the `post_sample_row_keys_with_metadata` interceptor.
+ """
+ return response
+
+ def post_sample_row_keys_with_metadata(
+ self,
+ response: rest_streaming.ResponseIterator,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]],
+ ) -> Tuple[
+ rest_streaming.ResponseIterator, Sequence[Tuple[str, Union[str, bytes]]]
+ ]:
+ """Post-rpc interceptor for sample_row_keys
+
+ Override in a subclass to read or manipulate the response or metadata after it
+ is returned by the Bigtable server but before it is returned to user code.
+
+ We recommend only using this `post_sample_row_keys_with_metadata`
+ interceptor in new development instead of the `post_sample_row_keys` interceptor.
+ When both interceptors are used, this `post_sample_row_keys_with_metadata` interceptor runs after the
+ `post_sample_row_keys` interceptor. The (possibly modified) response returned by
+ `post_sample_row_keys` will be passed to
+ `post_sample_row_keys_with_metadata`.
+ """
+ return response, metadata
+
+
+@dataclasses.dataclass
+class BigtableRestStub:
+ _session: AuthorizedSession
+ _host: str
+ _interceptor: BigtableRestInterceptor
+
+
+class BigtableRestTransport(_BaseBigtableRestTransport):
+ """REST backend synchronous transport for Bigtable.
+
+ Service for reading from and writing to existing Bigtable
+ tables.
+
+ This class defines the same methods as the primary client, so the
+ primary client can load the underlying transport implementation
+ and call it.
+
+ It sends JSON representations of protocol buffers over HTTP/1.1
+ """
+
+ def __init__(
+ self,
+ *,
+ host: str = "bigtable.googleapis.com",
+ credentials: Optional[ga_credentials.Credentials] = None,
+ credentials_file: Optional[str] = None,
+ scopes: Optional[Sequence[str]] = None,
+ client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None,
+ quota_project_id: Optional[str] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ always_use_jwt_access: Optional[bool] = False,
+ url_scheme: str = "https",
+ interceptor: Optional[BigtableRestInterceptor] = None,
+ api_audience: Optional[str] = None,
+ ) -> None:
+ """Instantiate the transport.
+
+ Args:
+ host (Optional[str]):
+ The hostname to connect to (default: 'bigtable.googleapis.com').
+ credentials (Optional[google.auth.credentials.Credentials]): The
+ authorization credentials to attach to requests. These
+ credentials identify the application to the service; if none
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+
+ credentials_file (Optional[str]): Deprecated. A file with credentials that can
+ be loaded with :func:`google.auth.load_credentials_from_file`.
+ This argument is ignored if ``channel`` is provided. This argument will be
+ removed in the next major version of this library.
+ scopes (Optional(Sequence[str])): A list of scopes. This argument is
+ ignored if ``channel`` is provided.
+ client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client
+ certificate to configure mutual TLS HTTP channel. It is ignored
+ if ``channel`` is provided.
+ quota_project_id (Optional[str]): An optional project to use for billing
+ and quota.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you are developing
+ your own client library.
+ always_use_jwt_access (Optional[bool]): Whether self signed JWT should
+ be used for service account credentials.
+ url_scheme: the protocol scheme for the API endpoint. Normally
+ "https", but for testing or local servers,
+ "http" can be specified.
+ """
+ # Run the base constructor
+ # TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc.
+ # TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the
+ # credentials object
+ super().__init__(
+ host=host,
+ credentials=credentials,
+ client_info=client_info,
+ always_use_jwt_access=always_use_jwt_access,
+ url_scheme=url_scheme,
+ api_audience=api_audience,
+ )
+ self._session = AuthorizedSession(
+ self._credentials, default_host=self.DEFAULT_HOST
+ )
+ if client_cert_source_for_mtls:
+ self._session.configure_mtls_channel(client_cert_source_for_mtls)
+ self._interceptor = interceptor or BigtableRestInterceptor()
+ self._prep_wrapped_messages(client_info)
+
+ class _CheckAndMutateRow(
+ _BaseBigtableRestTransport._BaseCheckAndMutateRow, BigtableRestStub
+ ):
+ def __hash__(self):
+ return hash("BigtableRestTransport.CheckAndMutateRow")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable.CheckAndMutateRowRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> bigtable.CheckAndMutateRowResponse:
+ r"""Call the check and mutate row method over HTTP.
+
+ Args:
+ request (~.bigtable.CheckAndMutateRowRequest):
+ The request object. Request message for
+ Bigtable.CheckAndMutateRow.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.bigtable.CheckAndMutateRowResponse:
+ Response message for
+ Bigtable.CheckAndMutateRow.
+
+ """
+
+ http_options = (
+ _BaseBigtableRestTransport._BaseCheckAndMutateRow._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_check_and_mutate_row(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableRestTransport._BaseCheckAndMutateRow._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableRestTransport._BaseCheckAndMutateRow._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableRestTransport._BaseCheckAndMutateRow._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable_v2.BigtableClient.CheckAndMutateRow",
+ extra={
+ "serviceName": "google.bigtable.v2.Bigtable",
+ "rpcName": "CheckAndMutateRow",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableRestTransport._CheckAndMutateRow._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = bigtable.CheckAndMutateRowResponse()
+ pb_resp = bigtable.CheckAndMutateRowResponse.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_check_and_mutate_row(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_check_and_mutate_row_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = bigtable.CheckAndMutateRowResponse.to_json(
+ response
+ )
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable_v2.BigtableClient.check_and_mutate_row",
+ extra={
+ "serviceName": "google.bigtable.v2.Bigtable",
+ "rpcName": "CheckAndMutateRow",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _ExecuteQuery(_BaseBigtableRestTransport._BaseExecuteQuery, BigtableRestStub):
+ def __hash__(self):
+ return hash("BigtableRestTransport.ExecuteQuery")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ stream=True,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable.ExecuteQueryRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> rest_streaming.ResponseIterator:
+ r"""Call the execute query method over HTTP.
+
+ Args:
+ request (~.bigtable.ExecuteQueryRequest):
+ The request object. Request message for
+ Bigtable.ExecuteQuery
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.bigtable.ExecuteQueryResponse:
+ Response message for
+ Bigtable.ExecuteQuery
+
+ """
+
+ http_options = (
+ _BaseBigtableRestTransport._BaseExecuteQuery._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_execute_query(request, metadata)
+ transcoded_request = (
+ _BaseBigtableRestTransport._BaseExecuteQuery._get_transcoded_request(
+ http_options, request
+ )
+ )
+
+ body = _BaseBigtableRestTransport._BaseExecuteQuery._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = (
+ _BaseBigtableRestTransport._BaseExecuteQuery._get_query_params_json(
+ transcoded_request
+ )
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable_v2.BigtableClient.ExecuteQuery",
+ extra={
+ "serviceName": "google.bigtable.v2.Bigtable",
+ "rpcName": "ExecuteQuery",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableRestTransport._ExecuteQuery._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = rest_streaming.ResponseIterator(
+ response, bigtable.ExecuteQueryResponse
+ )
+
+ resp = self._interceptor.post_execute_query(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_execute_query_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ http_response = {
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable_v2.BigtableClient.execute_query",
+ extra={
+ "serviceName": "google.bigtable.v2.Bigtable",
+ "rpcName": "ExecuteQuery",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _GenerateInitialChangeStreamPartitions(
+ _BaseBigtableRestTransport._BaseGenerateInitialChangeStreamPartitions,
+ BigtableRestStub,
+ ):
+ def __hash__(self):
+ return hash("BigtableRestTransport.GenerateInitialChangeStreamPartitions")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ stream=True,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable.GenerateInitialChangeStreamPartitionsRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> rest_streaming.ResponseIterator:
+ r"""Call the generate initial change
+ stream partitions method over HTTP.
+
+ Args:
+ request (~.bigtable.GenerateInitialChangeStreamPartitionsRequest):
+ The request object. NOTE: This API is intended to be used
+ by Apache Beam BigtableIO. Request
+ message for
+ Bigtable.GenerateInitialChangeStreamPartitions.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.bigtable.GenerateInitialChangeStreamPartitionsResponse:
+ NOTE: This API is intended to be used
+ by Apache Beam BigtableIO. Response
+ message for
+ Bigtable.GenerateInitialChangeStreamPartitions.
+
+ """
+
+ http_options = (
+ _BaseBigtableRestTransport._BaseGenerateInitialChangeStreamPartitions._get_http_options()
+ )
+
+ (
+ request,
+ metadata,
+ ) = self._interceptor.pre_generate_initial_change_stream_partitions(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableRestTransport._BaseGenerateInitialChangeStreamPartitions._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableRestTransport._BaseGenerateInitialChangeStreamPartitions._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableRestTransport._BaseGenerateInitialChangeStreamPartitions._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable_v2.BigtableClient.GenerateInitialChangeStreamPartitions",
+ extra={
+ "serviceName": "google.bigtable.v2.Bigtable",
+ "rpcName": "GenerateInitialChangeStreamPartitions",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableRestTransport._GenerateInitialChangeStreamPartitions._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = rest_streaming.ResponseIterator(
+ response, bigtable.GenerateInitialChangeStreamPartitionsResponse
+ )
+
+ resp = self._interceptor.post_generate_initial_change_stream_partitions(
+ resp
+ )
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ (
+ resp,
+ _,
+ ) = self._interceptor.post_generate_initial_change_stream_partitions_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ http_response = {
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable_v2.BigtableClient.generate_initial_change_stream_partitions",
+ extra={
+ "serviceName": "google.bigtable.v2.Bigtable",
+ "rpcName": "GenerateInitialChangeStreamPartitions",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _MutateRow(_BaseBigtableRestTransport._BaseMutateRow, BigtableRestStub):
+ def __hash__(self):
+ return hash("BigtableRestTransport.MutateRow")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable.MutateRowRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> bigtable.MutateRowResponse:
+ r"""Call the mutate row method over HTTP.
+
+ Args:
+ request (~.bigtable.MutateRowRequest):
+ The request object. Request message for
+ Bigtable.MutateRow.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.bigtable.MutateRowResponse:
+ Response message for
+ Bigtable.MutateRow.
+
+ """
+
+ http_options = _BaseBigtableRestTransport._BaseMutateRow._get_http_options()
+
+ request, metadata = self._interceptor.pre_mutate_row(request, metadata)
+ transcoded_request = (
+ _BaseBigtableRestTransport._BaseMutateRow._get_transcoded_request(
+ http_options, request
+ )
+ )
+
+ body = _BaseBigtableRestTransport._BaseMutateRow._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = (
+ _BaseBigtableRestTransport._BaseMutateRow._get_query_params_json(
+ transcoded_request
+ )
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable_v2.BigtableClient.MutateRow",
+ extra={
+ "serviceName": "google.bigtable.v2.Bigtable",
+ "rpcName": "MutateRow",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableRestTransport._MutateRow._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = bigtable.MutateRowResponse()
+ pb_resp = bigtable.MutateRowResponse.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_mutate_row(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_mutate_row_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = bigtable.MutateRowResponse.to_json(response)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable_v2.BigtableClient.mutate_row",
+ extra={
+ "serviceName": "google.bigtable.v2.Bigtable",
+ "rpcName": "MutateRow",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _MutateRows(_BaseBigtableRestTransport._BaseMutateRows, BigtableRestStub):
+ def __hash__(self):
+ return hash("BigtableRestTransport.MutateRows")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ stream=True,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable.MutateRowsRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> rest_streaming.ResponseIterator:
+ r"""Call the mutate rows method over HTTP.
+
+ Args:
+ request (~.bigtable.MutateRowsRequest):
+ The request object. Request message for
+ BigtableService.MutateRows.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.bigtable.MutateRowsResponse:
+ Response message for
+ BigtableService.MutateRows.
+
+ """
+
+ http_options = (
+ _BaseBigtableRestTransport._BaseMutateRows._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_mutate_rows(request, metadata)
+ transcoded_request = (
+ _BaseBigtableRestTransport._BaseMutateRows._get_transcoded_request(
+ http_options, request
+ )
+ )
+
+ body = _BaseBigtableRestTransport._BaseMutateRows._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = (
+ _BaseBigtableRestTransport._BaseMutateRows._get_query_params_json(
+ transcoded_request
+ )
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable_v2.BigtableClient.MutateRows",
+ extra={
+ "serviceName": "google.bigtable.v2.Bigtable",
+ "rpcName": "MutateRows",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableRestTransport._MutateRows._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = rest_streaming.ResponseIterator(
+ response, bigtable.MutateRowsResponse
+ )
+
+ resp = self._interceptor.post_mutate_rows(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_mutate_rows_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ http_response = {
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable_v2.BigtableClient.mutate_rows",
+ extra={
+ "serviceName": "google.bigtable.v2.Bigtable",
+ "rpcName": "MutateRows",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _PingAndWarm(_BaseBigtableRestTransport._BasePingAndWarm, BigtableRestStub):
+ def __hash__(self):
+ return hash("BigtableRestTransport.PingAndWarm")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable.PingAndWarmRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> bigtable.PingAndWarmResponse:
+ r"""Call the ping and warm method over HTTP.
+
+ Args:
+ request (~.bigtable.PingAndWarmRequest):
+ The request object. Request message for client connection
+ keep-alive and warming.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.bigtable.PingAndWarmResponse:
+ Response message for
+ Bigtable.PingAndWarm connection
+ keepalive and warming.
+
+ """
+
+ http_options = (
+ _BaseBigtableRestTransport._BasePingAndWarm._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_ping_and_warm(request, metadata)
+ transcoded_request = (
+ _BaseBigtableRestTransport._BasePingAndWarm._get_transcoded_request(
+ http_options, request
+ )
+ )
+
+ body = _BaseBigtableRestTransport._BasePingAndWarm._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = (
+ _BaseBigtableRestTransport._BasePingAndWarm._get_query_params_json(
+ transcoded_request
+ )
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable_v2.BigtableClient.PingAndWarm",
+ extra={
+ "serviceName": "google.bigtable.v2.Bigtable",
+ "rpcName": "PingAndWarm",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableRestTransport._PingAndWarm._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = bigtable.PingAndWarmResponse()
+ pb_resp = bigtable.PingAndWarmResponse.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_ping_and_warm(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_ping_and_warm_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = bigtable.PingAndWarmResponse.to_json(response)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable_v2.BigtableClient.ping_and_warm",
+ extra={
+ "serviceName": "google.bigtable.v2.Bigtable",
+ "rpcName": "PingAndWarm",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _PrepareQuery(_BaseBigtableRestTransport._BasePrepareQuery, BigtableRestStub):
+ def __hash__(self):
+ return hash("BigtableRestTransport.PrepareQuery")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable.PrepareQueryRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> bigtable.PrepareQueryResponse:
+ r"""Call the prepare query method over HTTP.
+
+ Args:
+ request (~.bigtable.PrepareQueryRequest):
+ The request object. Request message for
+ Bigtable.PrepareQuery
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.bigtable.PrepareQueryResponse:
+ Response message for
+ Bigtable.PrepareQueryResponse
+
+ """
+
+ http_options = (
+ _BaseBigtableRestTransport._BasePrepareQuery._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_prepare_query(request, metadata)
+ transcoded_request = (
+ _BaseBigtableRestTransport._BasePrepareQuery._get_transcoded_request(
+ http_options, request
+ )
+ )
+
+ body = _BaseBigtableRestTransport._BasePrepareQuery._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = (
+ _BaseBigtableRestTransport._BasePrepareQuery._get_query_params_json(
+ transcoded_request
+ )
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable_v2.BigtableClient.PrepareQuery",
+ extra={
+ "serviceName": "google.bigtable.v2.Bigtable",
+ "rpcName": "PrepareQuery",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableRestTransport._PrepareQuery._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = bigtable.PrepareQueryResponse()
+ pb_resp = bigtable.PrepareQueryResponse.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_prepare_query(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_prepare_query_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = bigtable.PrepareQueryResponse.to_json(response)
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable_v2.BigtableClient.prepare_query",
+ extra={
+ "serviceName": "google.bigtable.v2.Bigtable",
+ "rpcName": "PrepareQuery",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _ReadChangeStream(
+ _BaseBigtableRestTransport._BaseReadChangeStream, BigtableRestStub
+ ):
+ def __hash__(self):
+ return hash("BigtableRestTransport.ReadChangeStream")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ stream=True,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable.ReadChangeStreamRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> rest_streaming.ResponseIterator:
+ r"""Call the read change stream method over HTTP.
+
+ Args:
+ request (~.bigtable.ReadChangeStreamRequest):
+ The request object. NOTE: This API is intended to be used
+ by Apache Beam BigtableIO. Request
+ message for Bigtable.ReadChangeStream.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.bigtable.ReadChangeStreamResponse:
+ NOTE: This API is intended to be used
+ by Apache Beam BigtableIO. Response
+ message for Bigtable.ReadChangeStream.
+
+ """
+
+ http_options = (
+ _BaseBigtableRestTransport._BaseReadChangeStream._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_read_change_stream(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableRestTransport._BaseReadChangeStream._get_transcoded_request(
+ http_options, request
+ )
+
+ body = (
+ _BaseBigtableRestTransport._BaseReadChangeStream._get_request_body_json(
+ transcoded_request
+ )
+ )
+
+ # Jsonify the query params
+ query_params = (
+ _BaseBigtableRestTransport._BaseReadChangeStream._get_query_params_json(
+ transcoded_request
+ )
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable_v2.BigtableClient.ReadChangeStream",
+ extra={
+ "serviceName": "google.bigtable.v2.Bigtable",
+ "rpcName": "ReadChangeStream",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableRestTransport._ReadChangeStream._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = rest_streaming.ResponseIterator(
+ response, bigtable.ReadChangeStreamResponse
+ )
+
+ resp = self._interceptor.post_read_change_stream(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_read_change_stream_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ http_response = {
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable_v2.BigtableClient.read_change_stream",
+ extra={
+ "serviceName": "google.bigtable.v2.Bigtable",
+ "rpcName": "ReadChangeStream",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _ReadModifyWriteRow(
+ _BaseBigtableRestTransport._BaseReadModifyWriteRow, BigtableRestStub
+ ):
+ def __hash__(self):
+ return hash("BigtableRestTransport.ReadModifyWriteRow")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable.ReadModifyWriteRowRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> bigtable.ReadModifyWriteRowResponse:
+ r"""Call the read modify write row method over HTTP.
+
+ Args:
+ request (~.bigtable.ReadModifyWriteRowRequest):
+ The request object. Request message for
+ Bigtable.ReadModifyWriteRow.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.bigtable.ReadModifyWriteRowResponse:
+ Response message for
+ Bigtable.ReadModifyWriteRow.
+
+ """
+
+ http_options = (
+ _BaseBigtableRestTransport._BaseReadModifyWriteRow._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_read_modify_write_row(
+ request, metadata
+ )
+ transcoded_request = _BaseBigtableRestTransport._BaseReadModifyWriteRow._get_transcoded_request(
+ http_options, request
+ )
+
+ body = _BaseBigtableRestTransport._BaseReadModifyWriteRow._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = _BaseBigtableRestTransport._BaseReadModifyWriteRow._get_query_params_json(
+ transcoded_request
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable_v2.BigtableClient.ReadModifyWriteRow",
+ extra={
+ "serviceName": "google.bigtable.v2.Bigtable",
+ "rpcName": "ReadModifyWriteRow",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableRestTransport._ReadModifyWriteRow._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = bigtable.ReadModifyWriteRowResponse()
+ pb_resp = bigtable.ReadModifyWriteRowResponse.pb(resp)
+
+ json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
+
+ resp = self._interceptor.post_read_modify_write_row(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_read_modify_write_row_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ try:
+ response_payload = bigtable.ReadModifyWriteRowResponse.to_json(
+ response
+ )
+ except:
+ response_payload = None
+ http_response = {
+ "payload": response_payload,
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable_v2.BigtableClient.read_modify_write_row",
+ extra={
+ "serviceName": "google.bigtable.v2.Bigtable",
+ "rpcName": "ReadModifyWriteRow",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _ReadRows(_BaseBigtableRestTransport._BaseReadRows, BigtableRestStub):
+ def __hash__(self):
+ return hash("BigtableRestTransport.ReadRows")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ data=body,
+ stream=True,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable.ReadRowsRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> rest_streaming.ResponseIterator:
+ r"""Call the read rows method over HTTP.
+
+ Args:
+ request (~.bigtable.ReadRowsRequest):
+ The request object. Request message for
+ Bigtable.ReadRows.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.bigtable.ReadRowsResponse:
+ Response message for
+ Bigtable.ReadRows.
+
+ """
+
+ http_options = _BaseBigtableRestTransport._BaseReadRows._get_http_options()
+
+ request, metadata = self._interceptor.pre_read_rows(request, metadata)
+ transcoded_request = (
+ _BaseBigtableRestTransport._BaseReadRows._get_transcoded_request(
+ http_options, request
+ )
+ )
+
+ body = _BaseBigtableRestTransport._BaseReadRows._get_request_body_json(
+ transcoded_request
+ )
+
+ # Jsonify the query params
+ query_params = (
+ _BaseBigtableRestTransport._BaseReadRows._get_query_params_json(
+ transcoded_request
+ )
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable_v2.BigtableClient.ReadRows",
+ extra={
+ "serviceName": "google.bigtable.v2.Bigtable",
+ "rpcName": "ReadRows",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableRestTransport._ReadRows._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ body,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = rest_streaming.ResponseIterator(response, bigtable.ReadRowsResponse)
+
+ resp = self._interceptor.post_read_rows(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_read_rows_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ http_response = {
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable_v2.BigtableClient.read_rows",
+ extra={
+ "serviceName": "google.bigtable.v2.Bigtable",
+ "rpcName": "ReadRows",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ class _SampleRowKeys(
+ _BaseBigtableRestTransport._BaseSampleRowKeys, BigtableRestStub
+ ):
+ def __hash__(self):
+ return hash("BigtableRestTransport.SampleRowKeys")
+
+ @staticmethod
+ def _get_response(
+ host,
+ metadata,
+ query_params,
+ session,
+ timeout,
+ transcoded_request,
+ body=None,
+ ):
+ uri = transcoded_request["uri"]
+ method = transcoded_request["method"]
+ headers = dict(metadata)
+ headers["Content-Type"] = "application/json"
+ response = getattr(session, method)(
+ "{host}{uri}".format(host=host, uri=uri),
+ timeout=timeout,
+ headers=headers,
+ params=rest_helpers.flatten_query_params(query_params, strict=True),
+ stream=True,
+ )
+ return response
+
+ def __call__(
+ self,
+ request: bigtable.SampleRowKeysRequest,
+ *,
+ retry: OptionalRetry = gapic_v1.method.DEFAULT,
+ timeout: Optional[float] = None,
+ metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
+ ) -> rest_streaming.ResponseIterator:
+ r"""Call the sample row keys method over HTTP.
+
+ Args:
+ request (~.bigtable.SampleRowKeysRequest):
+ The request object. Request message for
+ Bigtable.SampleRowKeys.
+ retry (google.api_core.retry.Retry): Designation of what errors, if any,
+ should be retried.
+ timeout (float): The timeout for this request.
+ metadata (Sequence[Tuple[str, Union[str, bytes]]]): Key/value pairs which should be
+ sent along with the request as metadata. Normally, each value must be of type `str`,
+ but for metadata keys ending with the suffix `-bin`, the corresponding values must
+ be of type `bytes`.
+
+ Returns:
+ ~.bigtable.SampleRowKeysResponse:
+ Response message for
+ Bigtable.SampleRowKeys.
+
+ """
+
+ http_options = (
+ _BaseBigtableRestTransport._BaseSampleRowKeys._get_http_options()
+ )
+
+ request, metadata = self._interceptor.pre_sample_row_keys(request, metadata)
+ transcoded_request = (
+ _BaseBigtableRestTransport._BaseSampleRowKeys._get_transcoded_request(
+ http_options, request
+ )
+ )
+
+ # Jsonify the query params
+ query_params = (
+ _BaseBigtableRestTransport._BaseSampleRowKeys._get_query_params_json(
+ transcoded_request
+ )
+ )
+
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ request_url = "{host}{uri}".format(
+ host=self._host, uri=transcoded_request["uri"]
+ )
+ method = transcoded_request["method"]
+ try:
+ request_payload = type(request).to_json(request)
+ except:
+ request_payload = None
+ http_request = {
+ "payload": request_payload,
+ "requestMethod": method,
+ "requestUrl": request_url,
+ "headers": dict(metadata),
+ }
+ _LOGGER.debug(
+ f"Sending request for google.bigtable_v2.BigtableClient.SampleRowKeys",
+ extra={
+ "serviceName": "google.bigtable.v2.Bigtable",
+ "rpcName": "SampleRowKeys",
+ "httpRequest": http_request,
+ "metadata": http_request["headers"],
+ },
+ )
+
+ # Send the request
+ response = BigtableRestTransport._SampleRowKeys._get_response(
+ self._host,
+ metadata,
+ query_params,
+ self._session,
+ timeout,
+ transcoded_request,
+ )
+
+ # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
+ # subclass.
+ if response.status_code >= 400:
+ raise core_exceptions.from_http_response(response)
+
+ # Return the response
+ resp = rest_streaming.ResponseIterator(
+ response, bigtable.SampleRowKeysResponse
+ )
+
+ resp = self._interceptor.post_sample_row_keys(resp)
+ response_metadata = [(k, str(v)) for k, v in response.headers.items()]
+ resp, _ = self._interceptor.post_sample_row_keys_with_metadata(
+ resp, response_metadata
+ )
+ if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor(
+ logging.DEBUG
+ ): # pragma: NO COVER
+ http_response = {
+ "headers": dict(response.headers),
+ "status": response.status_code,
+ }
+ _LOGGER.debug(
+ "Received response for google.bigtable_v2.BigtableClient.sample_row_keys",
+ extra={
+ "serviceName": "google.bigtable.v2.Bigtable",
+ "rpcName": "SampleRowKeys",
+ "metadata": http_response["headers"],
+ "httpResponse": http_response,
+ },
+ )
+ return resp
+
+ @property
+ def check_and_mutate_row(
+ self,
+ ) -> Callable[
+ [bigtable.CheckAndMutateRowRequest], bigtable.CheckAndMutateRowResponse
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._CheckAndMutateRow(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def execute_query(
+ self,
+ ) -> Callable[[bigtable.ExecuteQueryRequest], bigtable.ExecuteQueryResponse]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._ExecuteQuery(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def generate_initial_change_stream_partitions(
+ self,
+ ) -> Callable[
+ [bigtable.GenerateInitialChangeStreamPartitionsRequest],
+ bigtable.GenerateInitialChangeStreamPartitionsResponse,
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._GenerateInitialChangeStreamPartitions(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def mutate_row(
+ self,
+ ) -> Callable[[bigtable.MutateRowRequest], bigtable.MutateRowResponse]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._MutateRow(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def mutate_rows(
+ self,
+ ) -> Callable[[bigtable.MutateRowsRequest], bigtable.MutateRowsResponse]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._MutateRows(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def ping_and_warm(
+ self,
+ ) -> Callable[[bigtable.PingAndWarmRequest], bigtable.PingAndWarmResponse]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._PingAndWarm(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def prepare_query(
+ self,
+ ) -> Callable[[bigtable.PrepareQueryRequest], bigtable.PrepareQueryResponse]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._PrepareQuery(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def read_change_stream(
+ self,
+ ) -> Callable[
+ [bigtable.ReadChangeStreamRequest], bigtable.ReadChangeStreamResponse
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._ReadChangeStream(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def read_modify_write_row(
+ self,
+ ) -> Callable[
+ [bigtable.ReadModifyWriteRowRequest], bigtable.ReadModifyWriteRowResponse
+ ]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._ReadModifyWriteRow(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def read_rows(
+ self,
+ ) -> Callable[[bigtable.ReadRowsRequest], bigtable.ReadRowsResponse]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._ReadRows(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def sample_row_keys(
+ self,
+ ) -> Callable[[bigtable.SampleRowKeysRequest], bigtable.SampleRowKeysResponse]:
+ # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
+ # In C++ this would require a dynamic_cast
+ return self._SampleRowKeys(self._session, self._host, self._interceptor) # type: ignore
+
+ @property
+ def kind(self) -> str:
+ return "rest"
+
+ def close(self):
+ self._session.close()
+
+
+__all__ = ("BigtableRestTransport",)
diff --git a/google/cloud/bigtable_v2/services/bigtable/transports/rest_base.py b/google/cloud/bigtable_v2/services/bigtable/transports/rest_base.py
new file mode 100644
index 000000000..5eab0ded4
--- /dev/null
+++ b/google/cloud/bigtable_v2/services/bigtable/transports/rest_base.py
@@ -0,0 +1,720 @@
+# -*- coding: utf-8 -*-
+# Copyright 2025 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 json # type: ignore
+from google.api_core import path_template
+from google.api_core import gapic_v1
+
+from google.protobuf import json_format
+from .base import BigtableTransport, DEFAULT_CLIENT_INFO
+
+import re
+from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union
+
+
+from google.cloud.bigtable_v2.types import bigtable
+
+
+class _BaseBigtableRestTransport(BigtableTransport):
+ """Base REST backend transport for Bigtable.
+
+ Note: This class is not meant to be used directly. Use its sync and
+ async sub-classes instead.
+
+ This class defines the same methods as the primary client, so the
+ primary client can load the underlying transport implementation
+ and call it.
+
+ It sends JSON representations of protocol buffers over HTTP/1.1
+ """
+
+ def __init__(
+ self,
+ *,
+ host: str = "bigtable.googleapis.com",
+ credentials: Optional[Any] = None,
+ client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
+ always_use_jwt_access: Optional[bool] = False,
+ url_scheme: str = "https",
+ api_audience: Optional[str] = None,
+ ) -> None:
+ """Instantiate the transport.
+ Args:
+ host (Optional[str]):
+ The hostname to connect to (default: 'bigtable.googleapis.com').
+ credentials (Optional[Any]): The
+ authorization credentials to attach to requests. These
+ credentials identify the application to the service; if none
+ are specified, the client will attempt to ascertain the
+ credentials from the environment.
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you are developing
+ your own client library.
+ always_use_jwt_access (Optional[bool]): Whether self signed JWT should
+ be used for service account credentials.
+ url_scheme: the protocol scheme for the API endpoint. Normally
+ "https", but for testing or local servers,
+ "http" can be specified.
+ """
+ # Run the base constructor
+ maybe_url_match = re.match("^(?Phttp(?:s)?://)?(?P.*)$", host)
+ if maybe_url_match is None:
+ raise ValueError(
+ f"Unexpected hostname structure: {host}"
+ ) # pragma: NO COVER
+
+ url_match_items = maybe_url_match.groupdict()
+
+ host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host
+
+ super().__init__(
+ host=host,
+ credentials=credentials,
+ client_info=client_info,
+ always_use_jwt_access=always_use_jwt_access,
+ api_audience=api_audience,
+ )
+
+ class _BaseCheckAndMutateRow:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{table_name=projects/*/instances/*/tables/*}:checkAndMutateRow",
+ "body": "*",
+ },
+ {
+ "method": "post",
+ "uri": "/v2/{authorized_view_name=projects/*/instances/*/tables/*/authorizedViews/*}:checkAndMutateRow",
+ "body": "*",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable.CheckAndMutateRowRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableRestTransport._BaseCheckAndMutateRow._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseExecuteQuery:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{instance_name=projects/*/instances/*}:executeQuery",
+ "body": "*",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable.ExecuteQueryRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableRestTransport._BaseExecuteQuery._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseGenerateInitialChangeStreamPartitions:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{table_name=projects/*/instances/*/tables/*}:generateInitialChangeStreamPartitions",
+ "body": "*",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable.GenerateInitialChangeStreamPartitionsRequest.pb(
+ request
+ )
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableRestTransport._BaseGenerateInitialChangeStreamPartitions._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseMutateRow:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{table_name=projects/*/instances/*/tables/*}:mutateRow",
+ "body": "*",
+ },
+ {
+ "method": "post",
+ "uri": "/v2/{authorized_view_name=projects/*/instances/*/tables/*/authorizedViews/*}:mutateRow",
+ "body": "*",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable.MutateRowRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableRestTransport._BaseMutateRow._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseMutateRows:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{table_name=projects/*/instances/*/tables/*}:mutateRows",
+ "body": "*",
+ },
+ {
+ "method": "post",
+ "uri": "/v2/{authorized_view_name=projects/*/instances/*/tables/*/authorizedViews/*}:mutateRows",
+ "body": "*",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable.MutateRowsRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableRestTransport._BaseMutateRows._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BasePingAndWarm:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{name=projects/*/instances/*}:ping",
+ "body": "*",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable.PingAndWarmRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableRestTransport._BasePingAndWarm._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BasePrepareQuery:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{instance_name=projects/*/instances/*}:prepareQuery",
+ "body": "*",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable.PrepareQueryRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableRestTransport._BasePrepareQuery._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseReadChangeStream:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{table_name=projects/*/instances/*/tables/*}:readChangeStream",
+ "body": "*",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable.ReadChangeStreamRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableRestTransport._BaseReadChangeStream._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseReadModifyWriteRow:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {}
+
+ @classmethod
+ def _get_unset_required_fields(cls, message_dict):
+ return {
+ k: v
+ for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items()
+ if k not in message_dict
+ }
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{table_name=projects/*/instances/*/tables/*}:readModifyWriteRow",
+ "body": "*",
+ },
+ {
+ "method": "post",
+ "uri": "/v2/{authorized_view_name=projects/*/instances/*/tables/*/authorizedViews/*}:readModifyWriteRow",
+ "body": "*",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable.ReadModifyWriteRowRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+ query_params.update(
+ _BaseBigtableRestTransport._BaseReadModifyWriteRow._get_unset_required_fields(
+ query_params
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseReadRows:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "post",
+ "uri": "/v2/{table_name=projects/*/instances/*/tables/*}:readRows",
+ "body": "*",
+ },
+ {
+ "method": "post",
+ "uri": "/v2/{authorized_view_name=projects/*/instances/*/tables/*/authorizedViews/*}:readRows",
+ "body": "*",
+ },
+ {
+ "method": "post",
+ "uri": "/v2/{materialized_view_name=projects/*/instances/*/materializedViews/*}:readRows",
+ "body": "*",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable.ReadRowsRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_request_body_json(transcoded_request):
+ # Jsonify the request body
+
+ body = json_format.MessageToJson(
+ transcoded_request["body"], use_integers_for_enums=True
+ )
+ return body
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+ class _BaseSampleRowKeys:
+ def __hash__(self): # pragma: NO COVER
+ return NotImplementedError("__hash__ must be implemented.")
+
+ @staticmethod
+ def _get_http_options():
+ http_options: List[Dict[str, str]] = [
+ {
+ "method": "get",
+ "uri": "/v2/{table_name=projects/*/instances/*/tables/*}:sampleRowKeys",
+ },
+ {
+ "method": "get",
+ "uri": "/v2/{authorized_view_name=projects/*/instances/*/tables/*/authorizedViews/*}:sampleRowKeys",
+ },
+ {
+ "method": "get",
+ "uri": "/v2/{materialized_view_name=projects/*/instances/*/materializedViews/*}:sampleRowKeys",
+ },
+ ]
+ return http_options
+
+ @staticmethod
+ def _get_transcoded_request(http_options, request):
+ pb_request = bigtable.SampleRowKeysRequest.pb(request)
+ transcoded_request = path_template.transcode(http_options, pb_request)
+ return transcoded_request
+
+ @staticmethod
+ def _get_query_params_json(transcoded_request):
+ query_params = json.loads(
+ json_format.MessageToJson(
+ transcoded_request["query_params"],
+ use_integers_for_enums=True,
+ )
+ )
+
+ query_params["$alt"] = "json;enum-encoding=int"
+ return query_params
+
+
+__all__ = ("_BaseBigtableRestTransport",)
diff --git a/google/cloud/bigtable_v2/types/__init__.py b/google/cloud/bigtable_v2/types/__init__.py
index 401705715..b13c076a2 100644
--- a/google/cloud/bigtable_v2/types/__init__.py
+++ b/google/cloud/bigtable_v2/types/__init__.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -16,12 +16,21 @@
from .bigtable import (
CheckAndMutateRowRequest,
CheckAndMutateRowResponse,
+ ExecuteQueryRequest,
+ ExecuteQueryResponse,
+ GenerateInitialChangeStreamPartitionsRequest,
+ GenerateInitialChangeStreamPartitionsResponse,
MutateRowRequest,
MutateRowResponse,
MutateRowsRequest,
MutateRowsResponse,
PingAndWarmRequest,
PingAndWarmResponse,
+ PrepareQueryRequest,
+ PrepareQueryResponse,
+ RateLimitInfo,
+ ReadChangeStreamRequest,
+ ReadChangeStreamResponse,
ReadModifyWriteRowRequest,
ReadModifyWriteRowResponse,
ReadRowsRequest,
@@ -30,45 +39,106 @@
SampleRowKeysResponse,
)
from .data import (
+ ArrayValue,
Cell,
Column,
+ ColumnMetadata,
ColumnRange,
Family,
+ Idempotency,
Mutation,
+ PartialResultSet,
+ ProtoFormat,
+ ProtoRows,
+ ProtoRowsBatch,
+ ProtoSchema,
ReadModifyWriteRule,
+ ResultSetMetadata,
Row,
RowFilter,
RowRange,
RowSet,
+ StreamContinuationToken,
+ StreamContinuationTokens,
+ StreamPartition,
TimestampRange,
+ Value,
ValueRange,
)
+from .feature_flags import (
+ FeatureFlags,
+)
+from .peer_info import (
+ PeerInfo,
+)
+from .request_stats import (
+ FullReadStatsView,
+ ReadIterationStats,
+ RequestLatencyStats,
+ RequestStats,
+)
+from .response_params import (
+ ResponseParams,
+)
+from .types import (
+ Type,
+)
__all__ = (
"CheckAndMutateRowRequest",
"CheckAndMutateRowResponse",
+ "ExecuteQueryRequest",
+ "ExecuteQueryResponse",
+ "GenerateInitialChangeStreamPartitionsRequest",
+ "GenerateInitialChangeStreamPartitionsResponse",
"MutateRowRequest",
"MutateRowResponse",
"MutateRowsRequest",
"MutateRowsResponse",
"PingAndWarmRequest",
"PingAndWarmResponse",
+ "PrepareQueryRequest",
+ "PrepareQueryResponse",
+ "RateLimitInfo",
+ "ReadChangeStreamRequest",
+ "ReadChangeStreamResponse",
"ReadModifyWriteRowRequest",
"ReadModifyWriteRowResponse",
"ReadRowsRequest",
"ReadRowsResponse",
"SampleRowKeysRequest",
"SampleRowKeysResponse",
+ "ArrayValue",
"Cell",
"Column",
+ "ColumnMetadata",
"ColumnRange",
"Family",
+ "Idempotency",
"Mutation",
+ "PartialResultSet",
+ "ProtoFormat",
+ "ProtoRows",
+ "ProtoRowsBatch",
+ "ProtoSchema",
"ReadModifyWriteRule",
+ "ResultSetMetadata",
"Row",
"RowFilter",
"RowRange",
"RowSet",
+ "StreamContinuationToken",
+ "StreamContinuationTokens",
+ "StreamPartition",
"TimestampRange",
+ "Value",
"ValueRange",
+ "FeatureFlags",
+ "PeerInfo",
+ "FullReadStatsView",
+ "ReadIterationStats",
+ "RequestLatencyStats",
+ "RequestStats",
+ "ResponseParams",
+ "Type",
)
diff --git a/google/cloud/bigtable_v2/types/bigtable.py b/google/cloud/bigtable_v2/types/bigtable.py
index 72785c264..19abba67b 100644
--- a/google/cloud/bigtable_v2/types/bigtable.py
+++ b/google/cloud/bigtable_v2/types/bigtable.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Copyright 2022 Google LLC
+# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -13,9 +13,17 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+from __future__ import annotations
+
+from typing import MutableMapping, MutableSequence
+
import proto # type: ignore
from google.cloud.bigtable_v2.types import data
+from google.cloud.bigtable_v2.types import request_stats as gb_request_stats
+from google.cloud.bigtable_v2.types import types
+from google.protobuf import duration_pb2 # type: ignore
+from google.protobuf import timestamp_pb2 # type: ignore
from google.protobuf import wrappers_pb2 # type: ignore
from google.rpc import status_pb2 # type: ignore
@@ -31,12 +39,21 @@
"MutateRowResponse",
"MutateRowsRequest",
"MutateRowsResponse",
+ "RateLimitInfo",
"CheckAndMutateRowRequest",
"CheckAndMutateRowResponse",
"PingAndWarmRequest",
"PingAndWarmResponse",
"ReadModifyWriteRowRequest",
"ReadModifyWriteRowResponse",
+ "GenerateInitialChangeStreamPartitionsRequest",
+ "GenerateInitialChangeStreamPartitionsResponse",
+ "ReadChangeStreamRequest",
+ "ReadChangeStreamResponse",
+ "ExecuteQueryRequest",
+ "ExecuteQueryResponse",
+ "PrepareQueryRequest",
+ "PrepareQueryResponse",
},
)
@@ -46,9 +63,22 @@ class ReadRowsRequest(proto.Message):
Attributes:
table_name (str):
- Required. The unique name of the table from which to read.
+ Optional. The unique name of the table from which to read.
+
Values are of the form
``projects//instances//tables/``.
+ authorized_view_name (str):
+ Optional. The unique name of the AuthorizedView from which
+ to read.
+
+ Values are of the form
+ ``projects//instances//tables//authorizedViews/``.
+ materialized_view_name (str):
+ Optional. The unique name of the MaterializedView from which
+ to read.
+
+ Values are of the form
+ ``projects//instances//materializedViews/``.
app_profile_id (str):
This value specifies routing for replication.
If not specified, the "default" application
@@ -65,37 +95,94 @@ class ReadRowsRequest(proto.Message):
The read will stop after committing to N
rows' worth of results. The default (zero) is to
return all results.
+ request_stats_view (google.cloud.bigtable_v2.types.ReadRowsRequest.RequestStatsView):
+ The view into RequestStats, as described
+ above.
+ reversed (bool):
+ Experimental API - Please note that this API is currently
+ experimental and can change in the future.
+
+ Return rows in lexiographical descending order of the row
+ keys. The row contents will not be affected by this flag.
+
+ Example result set:
+
+ ::
+
+ [
+ {key: "k2", "f:col1": "v1", "f:col2": "v1"},
+ {key: "k1", "f:col1": "v2", "f:col2": "v2"}
+ ]
"""
- table_name = proto.Field(
+ class RequestStatsView(proto.Enum):
+ r"""The desired view into RequestStats that should be returned in
+ the response.
+ See also: RequestStats message.
+
+ Values:
+ REQUEST_STATS_VIEW_UNSPECIFIED (0):
+ The default / unset value. The API will
+ default to the NONE option below.
+ REQUEST_STATS_NONE (1):
+ Do not include any RequestStats in the
+ response. This will leave the RequestStats
+ embedded message unset in the response.
+ REQUEST_STATS_FULL (2):
+ Include the full set of available
+ RequestStats in the response, applicable to this
+ read.
+ """
+ REQUEST_STATS_VIEW_UNSPECIFIED = 0
+ REQUEST_STATS_NONE = 1
+ REQUEST_STATS_FULL = 2
+
+ table_name: str = proto.Field(
proto.STRING,
number=1,
)
- app_profile_id = proto.Field(
+ authorized_view_name: str = proto.Field(
+ proto.STRING,
+ number=9,
+ )
+ materialized_view_name: str = proto.Field(
+ proto.STRING,
+ number=11,
+ )
+ app_profile_id: str = proto.Field(
proto.STRING,
number=5,
)
- rows = proto.Field(
+ rows: data.RowSet = proto.Field(
proto.MESSAGE,
number=2,
message=data.RowSet,
)
- filter = proto.Field(
+ filter: data.RowFilter = proto.Field(
proto.MESSAGE,
number=3,
message=data.RowFilter,
)
- rows_limit = proto.Field(
+ rows_limit: int = proto.Field(
proto.INT64,
number=4,
)
+ request_stats_view: RequestStatsView = proto.Field(
+ proto.ENUM,
+ number=6,
+ enum=RequestStatsView,
+ )
+ reversed: bool = proto.Field(
+ proto.BOOL,
+ number=7,
+ )
class ReadRowsResponse(proto.Message):
r"""Response message for Bigtable.ReadRows.
Attributes:
- chunks (Sequence[google.cloud.bigtable_v2.types.ReadRowsResponse.CellChunk]):
+ chunks (MutableSequence[google.cloud.bigtable_v2.types.ReadRowsResponse.CellChunk]):
A collection of a row's contents as part of
the read request.
last_scanned_row_key (bytes):
@@ -109,6 +196,13 @@ class ReadRowsResponse(proto.Message):
that was filtered out since the last committed
row key, allowing the client to skip that work
on a retry.
+ request_stats (google.cloud.bigtable_v2.types.RequestStats):
+ If requested, return enhanced query performance statistics.
+ The field request_stats is empty in a streamed response
+ unless the ReadRowsResponse message contains request_stats
+ in the last message of the stream. Always returned when
+ requested, even when the read request returns an empty
+ response.
"""
class CellChunk(proto.Message):
@@ -152,7 +246,7 @@ class CellChunk(proto.Message):
will only allow values of ``timestamp_micros`` which are
multiples of 1000. Timestamps are only set in the first
CellChunk per cell (for cells split into multiple chunks).
- labels (Sequence[str]):
+ labels (MutableSequence[str]):
Labels applied to the cell by a
[RowFilter][google.bigtable.v2.RowFilter]. Labels are only
set on the first CellChunk per cell.
@@ -182,56 +276,61 @@ class CellChunk(proto.Message):
This field is a member of `oneof`_ ``row_status``.
"""
- row_key = proto.Field(
+ row_key: bytes = proto.Field(
proto.BYTES,
number=1,
)
- family_name = proto.Field(
+ family_name: wrappers_pb2.StringValue = proto.Field(
proto.MESSAGE,
number=2,
message=wrappers_pb2.StringValue,
)
- qualifier = proto.Field(
+ qualifier: wrappers_pb2.BytesValue = proto.Field(
proto.MESSAGE,
number=3,
message=wrappers_pb2.BytesValue,
)
- timestamp_micros = proto.Field(
+ timestamp_micros: int = proto.Field(
proto.INT64,
number=4,
)
- labels = proto.RepeatedField(
+ labels: MutableSequence[str] = proto.RepeatedField(
proto.STRING,
number=5,
)
- value = proto.Field(
+ value: bytes = proto.Field(
proto.BYTES,
number=6,
)
- value_size = proto.Field(
+ value_size: int = proto.Field(
proto.INT32,
number=7,
)
- reset_row = proto.Field(
+ reset_row: bool = proto.Field(
proto.BOOL,
number=8,
oneof="row_status",
)
- commit_row = proto.Field(
+ commit_row: bool = proto.Field(
proto.BOOL,
number=9,
oneof="row_status",
)
- chunks = proto.RepeatedField(
+ chunks: MutableSequence[CellChunk] = proto.RepeatedField(
proto.MESSAGE,
number=1,
message=CellChunk,
)
- last_scanned_row_key = proto.Field(
+ last_scanned_row_key: bytes = proto.Field(
proto.BYTES,
number=2,
)
+ request_stats: gb_request_stats.RequestStats = proto.Field(
+ proto.MESSAGE,
+ number=3,
+ message=gb_request_stats.RequestStats,
+ )
class SampleRowKeysRequest(proto.Message):
@@ -239,20 +338,42 @@ class SampleRowKeysRequest(proto.Message):
Attributes:
table_name (str):
- Required. The unique name of the table from which to sample
- row keys. Values are of the form
+ Optional. The unique name of the table from which to sample
+ row keys.
+
+ Values are of the form
``projects//instances//tables/``.
+ authorized_view_name (str):
+ Optional. The unique name of the AuthorizedView from which
+ to sample row keys.
+
+ Values are of the form
+ ``projects//instances//tables//authorizedViews/``.
+ materialized_view_name (str):
+ Optional. The unique name of the MaterializedView from which
+ to read.
+
+ Values are of the form
+ ``projects//instances//materializedViews/``.
app_profile_id (str):
This value specifies routing for replication.
If not specified, the "default" application
profile will be used.
"""
- table_name = proto.Field(
+ table_name: str = proto.Field(
proto.STRING,
number=1,
)
- app_profile_id = proto.Field(
+ authorized_view_name: str = proto.Field(
+ proto.STRING,
+ number=4,
+ )
+ materialized_view_name: str = proto.Field(
+ proto.STRING,
+ number=5,
+ )
+ app_profile_id: str = proto.Field(
proto.STRING,
number=2,
)
@@ -282,11 +403,11 @@ class SampleRowKeysResponse(proto.Message):
fields.
"""
- row_key = proto.Field(
+ row_key: bytes = proto.Field(
proto.BYTES,
number=1,
)
- offset_bytes = proto.Field(
+ offset_bytes: int = proto.Field(
proto.INT64,
number=2,
)
@@ -297,9 +418,17 @@ class MutateRowRequest(proto.Message):
Attributes:
table_name (str):
- Required. The unique name of the table to which the mutation
- should be applied. Values are of the form
+ Optional. The unique name of the table to which the mutation
+ should be applied.
+
+ Values are of the form
``projects//instances//tables/``.
+ authorized_view_name (str):
+ Optional. The unique name of the AuthorizedView to which the
+ mutation should be applied.
+
+ Values are of the form
+ ``projects//instances//tables//authorizedViews/``.
app_profile_id (str):
This value specifies routing for replication.
If not specified, the "default" application
@@ -307,31 +436,44 @@ class MutateRowRequest(proto.Message):
row_key (bytes):
Required. The key of the row to which the
mutation should be applied.
- mutations (Sequence[google.cloud.bigtable_v2.types.Mutation]):
+ mutations (MutableSequence[google.cloud.bigtable_v2.types.Mutation]):
Required. Changes to be atomically applied to
the specified row. Entries are applied in order,
meaning that earlier mutations can be masked by
later ones. Must contain at least one entry and
at most 100000.
+ idempotency (google.cloud.bigtable_v2.types.Idempotency):
+ If set consistently across retries, prevents
+ this mutation from being double applied to
+ aggregate column families within a 15m window.
"""
- table_name = proto.Field(
+ table_name: str = proto.Field(
proto.STRING,
number=1,
)
- app_profile_id = proto.Field(
+ authorized_view_name: str = proto.Field(
+ proto.STRING,
+ number=6,
+ )
+ app_profile_id: str = proto.Field(
proto.STRING,
number=4,
)
- row_key = proto.Field(
+ row_key: bytes = proto.Field(
proto.BYTES,
number=2,
)
- mutations = proto.RepeatedField(
+ mutations: MutableSequence[data.Mutation] = proto.RepeatedField(
proto.MESSAGE,
number=3,
message=data.Mutation,
)
+ idempotency: data.Idempotency = proto.Field(
+ proto.MESSAGE,
+ number=8,
+ message=data.Idempotency,
+ )
class MutateRowResponse(proto.Message):
@@ -343,13 +485,22 @@ class MutateRowsRequest(proto.Message):
Attributes:
table_name (str):
- Required. The unique name of the table to
- which the mutations should be applied.
+ Optional. The unique name of the table to which the
+ mutations should be applied.
+
+ Values are of the form
+ ``projects//instances//tables/``.
+ authorized_view_name (str):
+ Optional. The unique name of the AuthorizedView to which the
+ mutations should be applied.
+
+ Values are of the form
+ ``projects//instances//tables//authorizedViews/``.
app_profile_id (str):
This value specifies routing for replication.
If not specified, the "default" application
profile will be used.
- entries (Sequence[google.cloud.bigtable_v2.types.MutateRowsRequest.Entry]):
+ entries (MutableSequence[google.cloud.bigtable_v2.types.MutateRowsRequest.Entry]):
Required. The row keys and corresponding
mutations to be applied in bulk. Each entry is
applied as an atomic mutation, but the entries
@@ -366,33 +517,46 @@ class Entry(proto.Message):
row_key (bytes):
The key of the row to which the ``mutations`` should be
applied.
- mutations (Sequence[google.cloud.bigtable_v2.types.Mutation]):
+ mutations (MutableSequence[google.cloud.bigtable_v2.types.Mutation]):
Required. Changes to be atomically applied to
the specified row. Mutations are applied in
order, meaning that earlier mutations can be
- masked by later ones.
- You must specify at least one mutation.
+ masked by later ones. You must specify at least
+ one mutation.
+ idempotency (google.cloud.bigtable_v2.types.Idempotency):
+ If set consistently across retries, prevents
+ this mutation from being double applied to
+ aggregate column families within a 15m window.
"""
- row_key = proto.Field(
+ row_key: bytes = proto.Field(
proto.BYTES,
number=1,
)
- mutations = proto.RepeatedField(
+ mutations: MutableSequence[data.Mutation] = proto.RepeatedField(
proto.MESSAGE,
number=2,
message=data.Mutation,
)
+ idempotency: data.Idempotency = proto.Field(
+ proto.MESSAGE,
+ number=3,
+ message=data.Idempotency,
+ )
- table_name = proto.Field(
+ table_name: str = proto.Field(
proto.STRING,
number=1,
)
- app_profile_id = proto.Field(
+ authorized_view_name: str = proto.Field(
+ proto.STRING,
+ number=5,
+ )
+ app_profile_id: str = proto.Field(
proto.STRING,
number=3,
)
- entries = proto.RepeatedField(
+ entries: MutableSequence[Entry] = proto.RepeatedField(
proto.MESSAGE,
number=2,
message=Entry,
@@ -402,10 +566,19 @@ class Entry(proto.Message):
class MutateRowsResponse(proto.Message):
r"""Response message for BigtableService.MutateRows.
+ .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields
+
Attributes:
- entries (Sequence[google.cloud.bigtable_v2.types.MutateRowsResponse.Entry]):
+ entries (MutableSequence[google.cloud.bigtable_v2.types.MutateRowsResponse.Entry]):
One or more results for Entries from the
batch request.
+ rate_limit_info (google.cloud.bigtable_v2.types.RateLimitInfo):
+ Information about how client should limit the
+ rate (QPS). Primirily used by supported official
+ Cloud Bigtable clients. If unset, the rate limit
+ info is not provided by the server.
+
+ This field is a member of `oneof`_ ``_rate_limit_info``.
"""
class Entry(proto.Message):
@@ -424,21 +597,65 @@ class Entry(proto.Message):
will be reported for both entries.
"""
- index = proto.Field(
+ index: int = proto.Field(
proto.INT64,
number=1,
)
- status = proto.Field(
+ status: status_pb2.Status = proto.Field(
proto.MESSAGE,
number=2,
message=status_pb2.Status,
)
- entries = proto.RepeatedField(
+ entries: MutableSequence[Entry] = proto.RepeatedField(
proto.MESSAGE,
number=1,
message=Entry,
)
+ rate_limit_info: "RateLimitInfo" = proto.Field(
+ proto.MESSAGE,
+ number=3,
+ optional=True,
+ message="RateLimitInfo",
+ )
+
+
+class RateLimitInfo(proto.Message):
+ r"""Information about how client should adjust the load to
+ Bigtable.
+
+ Attributes:
+ period (google.protobuf.duration_pb2.Duration):
+ Time that clients should wait before
+ adjusting the target rate again. If clients
+ adjust rate too frequently, the impact of the
+ previous adjustment may not have been taken into
+ account and may over-throttle or under-throttle.
+ If clients adjust rate too slowly, they will not
+ be responsive to load changes on server side,
+ and may over-throttle or under-throttle.
+ factor (float):
+ If it has been at least one ``period`` since the last load
+ adjustment, the client should multiply the current load by
+ this value to get the new target load. For example, if the
+ current load is 100 and ``factor`` is 0.8, the new target
+ load should be 80. After adjusting, the client should ignore
+ ``factor`` until another ``period`` has passed.
+
+ The client can measure its load using any unit that's
+ comparable over time. For example, QPS can be used as long
+ as each request involves a similar amount of work.
+ """
+
+ period: duration_pb2.Duration = proto.Field(
+ proto.MESSAGE,
+ number=1,
+ message=duration_pb2.Duration,
+ )
+ factor: float = proto.Field(
+ proto.DOUBLE,
+ number=2,
+ )
class CheckAndMutateRowRequest(proto.Message):
@@ -446,10 +663,17 @@ class CheckAndMutateRowRequest(proto.Message):
Attributes:
table_name (str):
- Required. The unique name of the table to which the
- conditional mutation should be applied. Values are of the
- form
+ Optional. The unique name of the table to which the
+ conditional mutation should be applied.
+
+ Values are of the form
``projects//instances//tables/``.
+ authorized_view_name (str):
+ Optional. The unique name of the AuthorizedView to which the
+ conditional mutation should be applied.
+
+ Values are of the form
+ ``projects//instances/