# Path: slo_generator/constants.py
# NO_DATA = -1
# MIN_VALID_EVENTS = int(os.environ.get("MIN_VALID_EVENTS", "1"))
# LATEST_MAJOR_VERSION = 'v2'
# COLORED_OUTPUT = int(os.environ.get("COLORED_OUTPUT", "0"))
# DRY_RUN = bool(int(os.environ.get("DRY_RUN", "0")))
# DEBUG = int(os.environ.get("DEBUG", "0"))
# V2_EXPORTERS = ('Pubsub', 'Cloudevent')
# CONFIG_SCHEMA = {
#     'backends': {},
#     'exporters': {},
#     'error_budget_policies': {},
# }
# SLO_CONFIG_SCHEMA = {
#     'apiVersion': '',
#     'kind': '',
#     'metadata': {},
#     'spec': {
#         'description': '',
#         'backend': '',
#         'method': '',
#         'exporters': [],
#         'service_level_indicator': {}
#     }
# }
# PROVIDERS_COMPAT = {
#     'Stackdriver': 'CloudMonitoring',
#     'StackdriverServiceMonitoring': 'CloudServiceMonitoring'
# }
# METRIC_LABELS_COMPAT = {
#     'goal': 'slo_target',
#     'description': 'slo_description',
#     'error_budget_burn_rate_threshold': 'alerting_burn_rate_threshold'
# }
# METRIC_METADATA_LABELS_TOP_COMPAT = ['service_name', 'feature_name', 'slo_name']
#     HEADER = '\033[95m'
#     OKBLUE = '\033[94m'
#     OKGREEN = '\033[92m'
#     WARNING = '\033[93m'
#     FAIL = '\033[91m'
#     ENDC = '\033[0m'
#     BOLD = '\033[1m'
#     UNDERLINE = '\033[4m'
# GREEN = Colors.OKGREEN
# RED = Colors.FAIL
# ENDC = Colors.ENDC
# BOLD = Colors.BOLD
# WARNING = Colors.WARNING
# FAIL = '❌'
# SUCCESS = '✅'
# RIGHT_ARROW = '➞'
# class Colors:


import io
import json
import logging
import pprint
import google.api_core
from google.cloud import bigquery
from slo_generator import constants
            obj: BigQuery table object.
        """
        table = self.client.get_table(table=table_ref)
        iostream = io.StringIO('')
        self.client.schema_to_json(table.schema, iostream)
        existing_schema = json.loads(iostream.getvalue())
        existing_fields = [field['name'] for field in existing_schema]
        LOGGER.debug(f'Existing fields: {existing_fields}')

        # Fields in TABLE_SCHEMA to add / remove
        updated_fields = [
            field['name']
            for field in TABLE_SCHEMA
            if field not in existing_schema
        ]
        extra_remote_fields = [
            field for field in existing_schema
            if field not in TABLE_SCHEMA and field['name'] in keep
        ]

        # If extra remote fields are detected in existing schema, update our
        # TABLE_SCHEMA with those
        if extra_remote_fields:
            LOGGER.info(f'Extra remote BigQuery fields: {extra_remote_fields}')
            TABLE_SCHEMA.extend(extra_remote_fields)

        # If new fields are detected in TABLE_SCHEMA, update BigQuery schema
        if updated_fields:
            LOGGER.info(f'Updated BigQuery fields: {updated_fields}')
            table.schema = BigqueryExporter.build_schema(TABLE_SCHEMA)

# Path: slo_generator/constants.py
# NO_DATA = -1
# MIN_VALID_EVENTS = int(os.environ.get("MIN_VALID_EVENTS", "1"))
# LATEST_MAJOR_VERSION = 'v2'
# COLORED_OUTPUT = int(os.environ.get("COLORED_OUTPUT", "0"))
# DRY_RUN = bool(int(os.environ.get("DRY_RUN", "0")))
# DEBUG = int(os.environ.get("DEBUG", "0"))
# V2_EXPORTERS = ('Pubsub', 'Cloudevent')
# CONFIG_SCHEMA = {
#     'backends': {},
#     'exporters': {},
#     'error_budget_policies': {},
# }
# SLO_CONFIG_SCHEMA = {
#     'apiVersion': '',
#     'kind': '',
#     'metadata': {},
#     'spec': {
#         'description': '',
#         'backend': '',
#         'method': '',
#         'exporters': [],
#         'service_level_indicator': {}
#     }
# }
# PROVIDERS_COMPAT = {
#     'Stackdriver': 'CloudMonitoring',
#     'StackdriverServiceMonitoring': 'CloudServiceMonitoring'
# }
# METRIC_LABELS_COMPAT = {
#     'goal': 'slo_target',
#     'description': 'slo_description',
#     'error_budget_burn_rate_threshold': 'alerting_burn_rate_threshold'
# }
# METRIC_METADATA_LABELS_TOP_COMPAT = ['service_name', 'feature_name', 'slo_name']
#     HEADER = '\033[95m'
#     OKBLUE = '\033[94m'
#     OKGREEN = '\033[92m'
#     WARNING = '\033[93m'
#     FAIL = '\033[91m'
#     ENDC = '\033[0m'
#     BOLD = '\033[1m'
#     UNDERLINE = '\033[4m'
# GREEN = Colors.OKGREEN
# RED = Colors.FAIL
# ENDC = Colors.ENDC
# BOLD = Colors.BOLD
# WARNING = Colors.WARNING
# FAIL = '❌'
# SUCCESS = '✅'
# RIGHT_ARROW = '➞'
# class Colors:


# Path: slo_generator/exporters/bigquery.py
import io
import json
import logging
import pprint
import google.api_core
from google.cloud import bigquery
from slo_generator import constants

            obj: BigQuery table object.
        """
        table = self.client.get_table(table=table_ref)
        iostream = io.StringIO('')
        self.client.schema_to_json(table.schema, iostream)
        existing_schema = json.loads(iostream.getvalue())
        existing_fields = [field['name'] for field in existing_schema]
        LOGGER.debug(f'Existing fields: {existing_fields}')

        # Fields in TABLE_SCHEMA to add / remove
        updated_fields = [
            field['name']
            for field in TABLE_SCHEMA
            if field not in existing_schema
        ]
        extra_remote_fields = [
            field for field in existing_schema
            if field not in TABLE_SCHEMA and field['name'] in keep
        ]

        # If extra remote fields are detected in existing schema, update our
        # TABLE_SCHEMA with those
        if extra_remote_fields:
            LOGGER.info(f'Extra remote BigQuery fields: {extra_remote_fields}')
            TABLE_SCHEMA.extend(extra_remote_fields)

        # If new fields are detected in TABLE_SCHEMA, update BigQuery schema
        if updated_fields:
            LOGGER.info(f'Updated BigQuery fields: {updated_fields}')
            table.schema = BigqueryExporter.build_schema(TABLE_SCHEMA)

            if constants.DRY_RUN: