Skip to content

Commit 78f4001

Browse files
authored
fix: allow bigframes.options.bigquery.credentials to be None (#2092)
* fix: allow bigframes.options.bigquery.credentials to be `None` This is a partial revert of "perf: avoid re-authenticating if credentials have already been fetched (#2058)", commit 913de1b. * add unit test
1 parent 81dbf9a commit 78f4001

File tree

4 files changed

+18
-45
lines changed

4 files changed

+18
-45
lines changed

bigframes/_config/bigquery_options.py

Lines changed: 3 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import google.auth.credentials
2323
import requests.adapters
2424

25-
import bigframes._config.auth
2625
import bigframes._importing
2726
import bigframes.enums
2827
import bigframes.exceptions as bfe
@@ -38,7 +37,6 @@
3837

3938
def _get_validated_location(value: Optional[str]) -> Optional[str]:
4039
import bigframes._tools.strings
41-
import bigframes.constants
4240

4341
if value is None or value in bigframes.constants.ALL_BIGQUERY_LOCATIONS:
4442
return value
@@ -143,52 +141,20 @@ def application_name(self, value: Optional[str]):
143141
)
144142
self._application_name = value
145143

146-
def _try_set_default_credentials_and_project(
147-
self,
148-
) -> tuple[google.auth.credentials.Credentials, Optional[str]]:
149-
# Don't fetch credentials or project if credentials is already set.
150-
# If it's set, we've already authenticated, so if the user wants to
151-
# re-auth, they should explicitly reset the credentials.
152-
if self._credentials is not None:
153-
return self._credentials, self._project
154-
155-
(
156-
credentials,
157-
credentials_project,
158-
) = bigframes._config.auth.get_default_credentials_with_project()
159-
self._credentials = credentials
160-
161-
# Avoid overriding an explicitly set project with a default value.
162-
if self._project is None:
163-
self._project = credentials_project
164-
165-
return credentials, self._project
166-
167144
@property
168-
def credentials(self) -> google.auth.credentials.Credentials:
145+
def credentials(self) -> Optional[google.auth.credentials.Credentials]:
169146
"""The OAuth2 credentials to use for this client.
170147
171-
Set to None to force re-authentication.
172-
173148
Returns:
174149
None or google.auth.credentials.Credentials:
175150
google.auth.credentials.Credentials if exists; otherwise None.
176151
"""
177-
if self._credentials:
178-
return self._credentials
179-
180-
credentials, _ = self._try_set_default_credentials_and_project()
181-
return credentials
152+
return self._credentials
182153

183154
@credentials.setter
184155
def credentials(self, value: Optional[google.auth.credentials.Credentials]):
185156
if self._session_started and self._credentials is not value:
186157
raise ValueError(SESSION_STARTED_MESSAGE.format(attribute="credentials"))
187-
188-
if value is None:
189-
# The user has _explicitly_ asked that we re-authenticate.
190-
bigframes._config.auth.reset_default_credentials_and_project()
191-
192158
self._credentials = value
193159

194160
@property
@@ -217,11 +183,7 @@ def project(self) -> Optional[str]:
217183
None or str:
218184
Google Cloud project ID as a string; otherwise None.
219185
"""
220-
if self._project:
221-
return self._project
222-
223-
_, project = self._try_set_default_credentials_and_project()
224-
return project
186+
return self._project
225187

226188
@project.setter
227189
def project(self, value: Optional[str]):

bigframes/session/clients.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
import google.cloud.storage # type: ignore
3333
import requests
3434

35-
import bigframes._config
35+
import bigframes._config.auth
3636
import bigframes.constants
3737
import bigframes.version
3838

@@ -50,6 +50,10 @@
5050
_BIGQUERYSTORAGE_REGIONAL_ENDPOINT = "bigquerystorage.{location}.rep.googleapis.com"
5151

5252

53+
def _get_default_credentials_with_project():
54+
return bigframes._config.auth.get_default_credentials_with_project()
55+
56+
5357
def _get_application_names():
5458
apps = [_APPLICATION_NAME]
5559

@@ -84,8 +88,7 @@ def __init__(
8488
):
8589
credentials_project = None
8690
if credentials is None:
87-
credentials = bigframes._config.options.bigquery.credentials
88-
credentials_project = bigframes._config.options.bigquery.project
91+
credentials, credentials_project = _get_default_credentials_with_project()
8992

9093
# Prefer the project in this order:
9194
# 1. Project explicitly specified by the user

tests/unit/_config/test_bigquery_options.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,3 +203,8 @@ def test_default_options():
203203

204204
assert options.allow_large_results is False
205205
assert options.ordering_mode == "strict"
206+
207+
# We should default to None as an indicator that the user hasn't set these
208+
# explicitly. See internal issue b/445731915.
209+
assert options.credentials is None
210+
assert options.project is None

tests/unit/pandas/io/test_api.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import google.cloud.bigquery
1818
import pytest
1919

20+
import bigframes._config.auth
2021
import bigframes.dataframe
2122
import bigframes.pandas
2223
import bigframes.pandas.io.api as bf_io_api
@@ -50,7 +51,7 @@ def test_read_gbq_colab_dry_run_doesnt_call_set_location(
5051
mock_set_location.assert_not_called()
5152

5253

53-
@mock.patch("bigframes._config.auth.get_default_credentials_with_project")
54+
@mock.patch("bigframes._config.auth.pydata_google_auth.default")
5455
@mock.patch("bigframes.core.global_session.with_default_session")
5556
def test_read_gbq_colab_dry_run_doesnt_authenticate_multiple_times(
5657
mock_with_default_session, mock_get_credentials, monkeypatch
@@ -77,12 +78,14 @@ def test_read_gbq_colab_dry_run_doesnt_authenticate_multiple_times(
7778
mock_df = mock.create_autospec(bigframes.dataframe.DataFrame)
7879
mock_with_default_session.return_value = mock_df
7980

81+
bigframes._config.auth._cached_credentials = None
8082
query_or_table = "SELECT {param1} AS param1"
8183
sample_pyformat_args = {"param1": "value1"}
8284
bf_io_api._read_gbq_colab(
8385
query_or_table, pyformat_args=sample_pyformat_args, dry_run=True
8486
)
8587

88+
mock_get_credentials.assert_called()
8689
mock_with_default_session.assert_not_called()
8790
mock_get_credentials.reset_mock()
8891

0 commit comments

Comments
 (0)