import os from google.auth.credentials import AnonymousCredentials from google.cloud.bigtable import Client from google.cloud.bigtable.instance import Instance from google.cloud.bigtable.table import Table from delphi_api.const import BIGTABLE_APP_PROFILE_ID, BIGTABLE_INSTANCE_ID, ENVIRONMENT class BigTableClient: @staticmethod def get_client(**kwargs): """ Available kwargs: project=None, credentials=None, read_only=False, admin=False, client_info=_CLIENT_INFO, client_options=None, admin_client_options=None, channel=None, """ if os.getenv('BIGTABLE_EMULATOR_HOST') or ENVIRONMENT == 'test': # pragma: no cover # This for testing, and here due to a bug in the gcloud client that does not # _only_ read the environment variable to establish a connection to the emulator return Client(project='emulated-project', credentials=AnonymousCredentials(), admin=True) return Client(**kwargs) # Reuse a single service object to reduce open files/connections _BIGTABLE_READ_ONLY_CLIENT = BigTableClient.get_client(read_only=True) class BigTableService: def __init__(self, table_id: str, instance_id: str = BIGTABLE_INSTANCE_ID, app_profile_id: str = BIGTABLE_APP_PROFILE_ID): """Class to include config and encapsulate BigTable API Args: table_id: BigTable TABLE_ID instance_id: BigTable INSTANCE_ID app_profile_id: BigTable application profile ID """ self.table_id = table_id self.instance_id = instance_id self.app_profile_id = app_profile_id @staticmethod def _get_client(**kwargs): return BigTableClient.get_client(**kwargs) @property def client(self) -> Client: return _BIGTABLE_READ_ONLY_CLIENT @property def instance(self) -> Instance: return self.client.instance(self.instance_id) @property def table(self) -> Table: return self.instance.table(self.table_id, app_profile_id=self.app_profile_id) @property def admin_client(self) -> Client: return BigTableClient.get_client(admin=True) @property def admin_instance(self) -> Instance: return self.admin_client.instance(self.instance_id) @property def admin_table(self) -> Table: return self.admin_instance.table(self.table_id, app_profile_id=self.app_profile_id)