Skip to content

Commit 34148f8

Browse files
committed
move lock to module
1 parent a91fbe0 commit 34148f8

File tree

2 files changed

+50
-23
lines changed

2 files changed

+50
-23
lines changed

bigframes/_config/auth.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,44 @@
1414

1515
from __future__ import annotations
1616

17+
import threading
1718
from typing import Optional
1819

1920
import google.auth.credentials
21+
import google.auth.transport.requests
2022
import pydata_google_auth
2123

2224
_SCOPES = ["https://www.googleapis.com/auth/cloud-platform"]
2325

26+
# Put the lock here rather than in BigQueryOptions so that BigQueryOptions
27+
# remains deepcopy-able.
28+
_AUTH_LOCK = threading.Lock()
29+
_cached_credentials: Optional[google.auth.credentials.Credentials] = None
30+
_cached_project_default: Optional[str] = None
31+
2432

2533
def get_default_credentials_with_project() -> tuple[
2634
google.auth.credentials.Credentials, Optional[str]
2735
]:
28-
return pydata_google_auth.default(scopes=_SCOPES, use_local_webserver=False)
36+
global _AUTH_LOCK, _cached_credentials, _cached_project_default
37+
38+
with _AUTH_LOCK:
39+
if _cached_credentials is not None:
40+
return _cached_credentials, _cached_project_default
41+
42+
_cached_credentials, _cached_project_default = pydata_google_auth.default(
43+
scopes=_SCOPES, use_local_webserver=False
44+
)
45+
46+
# Ensure an access token is available.
47+
_cached_credentials.refresh(google.auth.transport.requests.Request())
48+
49+
return _cached_credentials, _cached_project_default
50+
51+
52+
def reset_default_credentials_and_project():
53+
global _AUTH_LOCK, _cached_credentials, _cached_project_default
54+
55+
with _AUTH_LOCK:
56+
_cached_credentials = None
57+
_cached_project_default = None

bigframes/_config/bigquery_options.py

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,10 @@
1616

1717
from __future__ import annotations
1818

19-
import threading
2019
from typing import Literal, Optional, Sequence, Tuple
2120
import warnings
2221

2322
import google.auth.credentials
24-
import google.auth.transport.requests
2523
import requests.adapters
2624

2725
import bigframes._config.auth
@@ -101,7 +99,6 @@ def __init__(
10199
] = (),
102100
enable_polars_execution: bool = False,
103101
):
104-
self._credentials_and_project_lock = threading.Lock()
105102
self._credentials = credentials
106103
self._project = project
107104
self._location = _get_validated_location(location)
@@ -149,27 +146,23 @@ def application_name(self, value: Optional[str]):
149146
def _try_set_default_credentials_and_project(
150147
self,
151148
) -> tuple[google.auth.credentials.Credentials, Optional[str]]:
152-
with self._credentials_and_project_lock:
153-
# Don't fetch credentials or project if credentials is already set.
154-
# If it's set, we've already authenticated, so if the user wants to
155-
# re-auth, they should explicitly reset the credentials.
156-
if self._credentials is not None:
157-
return self._credentials, self._project
158-
159-
(
160-
credentials,
161-
credentials_project,
162-
) = bigframes._config.auth.get_default_credentials_with_project()
163-
164-
# Ensure an access token is available.
165-
credentials.refresh(google.auth.transport.requests.Request())
166-
self._credentials = credentials
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
167160

168-
# Avoid overriding an explicitly set project with a default value.
169-
if self._project is None:
170-
self._project = credentials_project
161+
# Avoid overriding an explicitly set project with a default value.
162+
if self._project is None:
163+
self._project = credentials_project
171164

172-
return credentials, credentials_project
165+
return credentials, self._project
173166

174167
@property
175168
def credentials(self) -> google.auth.credentials.Credentials:
@@ -191,6 +184,11 @@ def credentials(self) -> google.auth.credentials.Credentials:
191184
def credentials(self, value: Optional[google.auth.credentials.Credentials]):
192185
if self._session_started and self._credentials is not value:
193186
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+
194192
self._credentials = value
195193

196194
@property

0 commit comments

Comments
 (0)