Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Bigquery Emulator settings to be set #1017

Open
wants to merge 26 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
9622652
Allow Bigquery Emulator settings to be set
OTooleMichael Nov 10, 2023
c13d264
Switch Connection ordering on api_enpoint
OTooleMichael Nov 11, 2023
49b848e
Merge branch 'main' into patch-1
colin-rogers-dbt Dec 4, 2023
85cbcb7
Merge branch 'main' into patch-1
OTooleMichael Feb 14, 2024
b2aa0df
Basic test to lock in that "api_endpoint" is a credentials field that…
OTooleMichael Feb 27, 2024
03b6a6d
Example ApiEndpoint typo
OTooleMichael Feb 27, 2024
03514b5
Merge branch 'main' into patch-1
OTooleMichael Feb 27, 2024
4a853b3
Merge branch 'main' into patch-1
OTooleMichael Mar 1, 2024
a374786
Merge branch 'main' into patch-1
OTooleMichael Mar 5, 2024
326d6ae
Merge branch 'main' into patch-1
OTooleMichael Mar 11, 2024
9478ae9
Linting/Black bump
OTooleMichael Mar 18, 2024
a9ee098
Correct call signature
OTooleMichael Mar 18, 2024
9cfb1a6
Merge branch 'main' into patch-1
OTooleMichael Mar 20, 2024
ca5c885
Merge branch 'main' into patch-1
MichelleArk Mar 22, 2024
28009c9
Break out client mock args for clarity
OTooleMichael Mar 24, 2024
5d51658
Clear caching between tests
OTooleMichael Mar 25, 2024
b5ec4a3
Merge branch 'main' into patch-1
OTooleMichael Mar 25, 2024
7912f75
Merge branch 'main' into patch-1
OTooleMichael Mar 27, 2024
c2b2b49
Merge branch 'main' into patch-1
OTooleMichael Mar 30, 2024
08c033d
Merge branch 'main' into patch-1
OTooleMichael Apr 4, 2024
bbc2826
Merge branch 'main' into patch-1
OTooleMichael Apr 18, 2024
eea3241
Merge branch 'main' into patch-1
OTooleMichael Apr 21, 2024
7673691
Merge branch 'main' into patch-1
OTooleMichael May 11, 2024
7918624
Merge branch 'main' into patch-1
OTooleMichael Jul 16, 2024
27eec86
Merge branch 'main' into patch-1
OTooleMichael Aug 7, 2024
e07004e
Merge branch 'main' into patch-1
OTooleMichael Sep 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion dbt/adapters/bigquery/connections.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import google.auth.exceptions
import google.cloud.bigquery
import google.cloud.exceptions
from google.api_core import retry, client_info
from google.api_core import retry, client_info, client_options
from google.auth import impersonated_credentials
from google.oauth2 import (
credentials as GoogleCredentials,
Expand Down Expand Up @@ -126,6 +126,7 @@ class BigQueryCredentials(Credentials):
schema: Optional[str] = None
execution_project: Optional[str] = None
location: Optional[str] = None
api_endpoint: Optional[str] = None
priority: Optional[Priority] = None
maximum_bytes_billed: Optional[int] = None
impersonate_service_account: Optional[str] = None
Expand Down Expand Up @@ -405,13 +406,19 @@ def get_bigquery_client(cls, profile_credentials):
creds = cls.get_credentials(profile_credentials)
execution_project = profile_credentials.execution_project
location = getattr(profile_credentials, "location", None)
options: Optional[client_options.ClientOptions] = None
if profile_credentials.api_endpoint:
options = client_options.ClientOptions(
api_endpoint=profile_credentials.api_endpoint,
)

info = client_info.ClientInfo(user_agent=f"dbt-bigquery-{dbt_version.version}")
return google.cloud.bigquery.Client(
execution_project,
creds,
location=location,
client_info=info,
client_options=options,
)

@classmethod
Expand Down
48 changes: 47 additions & 1 deletion tests/unit/test_bigquery_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from dbt.adapters.bigquery.relation_configs import PartitionConfig
from dbt.adapters.bigquery import BigQueryAdapter, BigQueryRelation
from google.cloud.bigquery.table import Table
from dbt.adapters.bigquery.connections import _sanitize_label, _VALIDATE_LABEL_LENGTH_LIMIT
from dbt.adapters.bigquery.connections import _sanitize_label, _VALIDATE_LABEL_LENGTH_LIMIT, get_bigquery_defaults
from dbt_common.clients import agate_helper
import dbt_common.exceptions
from dbt.context.query_header import generate_query_header_context
Expand Down Expand Up @@ -71,6 +71,17 @@ def setUp(self):
"priority": "batch",
"maximum_bytes_billed": 0,
},
"api_endpoint": {
"type": "bigquery",
"method": "oauth",
"project": "dbt-unit-000000",
"schema": "dummy_schema",
"threads": 1,
"location": "Luna Station",
"priority": "batch",
"maximum_bytes_billed": 0,
"api_endpoint": "https://localhost:3001",
},
"impersonate": {
"type": "bigquery",
"method": "oauth",
Expand Down Expand Up @@ -389,6 +400,7 @@ def test_cancel_open_connections_single(self):
@patch("dbt.adapters.bigquery.impl.google.auth.default")
@patch("dbt.adapters.bigquery.impl.google.cloud.bigquery")
def test_location_user_agent(self, mock_bq, mock_auth_default):
get_bigquery_defaults.cache_clear()
creds = MagicMock()
mock_auth_default.return_value = (creds, MagicMock())
adapter = self.get_adapter("loc")
Expand All @@ -403,8 +415,42 @@ def test_location_user_agent(self, mock_bq, mock_auth_default):
creds,
location="Luna Station",
client_info=HasUserAgent(),
client_options=None,
)

@patch("dbt.adapters.bigquery.impl.google.auth.default")
@patch("dbt.adapters.bigquery.impl.google.cloud.bigquery")
def test_api_endpoint_settable(self, mock_bq, mock_auth_default):
"""Ensure that a user can pass api_endpoint to the connector eg. for emulator."""

get_bigquery_defaults.cache_clear()
creds = MagicMock()
mock_auth_default.return_value = (creds, MagicMock())
adapter = self.get_adapter("api_endpoint")

connection = adapter.acquire_connection("dummy")
mock_client = mock_bq.Client

mock_client.assert_not_called()
connection.handle
mock_client.assert_called_once_with(
"dbt-unit-000000",
creds,
location="Luna Station",
client_info=HasUserAgent(),
client_options=_CheckApiEndpointSet("https://localhost:3001"),
)


class _CheckApiEndpointSet:
value: str

def __init__(self, value: str) -> None:
self.value = value

def __eq__(self, other) -> bool:
return getattr(other, "api_endpoint") == self.value


class HasUserAgent:
PAT = re.compile(r"dbt-bigquery-\d+\.\d+\.\d+((a|b|rc)\d+)?")
Expand Down