Skip to content

Commit 08590bd

Browse files
authored
ENH: deprecate private_key argument (#240)
The argument was already deprecated in the function docs. This commit adds a warning when using pandas 0.24 or greater (the first version to include the credentials argument).
1 parent 398e75e commit 08590bd

File tree

3 files changed

+123
-3
lines changed

3 files changed

+123
-3
lines changed

docs/source/howto/authentication.rst

+8-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ To use service account credentials, set the ``credentials`` parameter to the res
2525

2626
.. code:: python
2727
28-
credentials = google.oauth2.service_account.Credentials.from_service_account_file(
28+
from google.oauth2 import service_account
29+
import pandas_gbq
30+
31+
credentials = service_account.Credentials.from_service_account_file(
2932
'path/to/key.json',
3033
)
3134
df = pandas_gbq.read_gbq(sql, project_id="YOUR-PROJECT-ID", credentials=credentials)
@@ -35,7 +38,10 @@ To use service account credentials, set the ``credentials`` parameter to the res
3538

3639
.. code:: python
3740
38-
credentials = google.oauth2.service_account.Credentials.from_service_account_info(
41+
from google.oauth2 import service_account
42+
import pandas_gbq
43+
44+
credentials = service_account.Credentials.from_service_account_info(
3945
{
4046
"type": "service_account",
4147
"project_id": "YOUR-PROJECT-ID",

pandas_gbq/gbq.py

+22-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@
1414

1515
BIGQUERY_INSTALLED_VERSION = None
1616
SHOW_VERBOSE_DEPRECATION = False
17+
SHOW_PRIVATE_KEY_DEPRECATION = False
18+
PRIVATE_KEY_DEPRECATION_MESSAGE = (
19+
"private_key is deprecated and will be removed in a future version."
20+
"Use the credentials argument instead. See "
21+
"https://pandas-gbq.readthedocs.io/en/latest/howto/authentication.html "
22+
"for examples on using the credentials argument with service account keys."
23+
)
1724

1825
try:
1926
import tqdm # noqa
@@ -22,7 +29,7 @@
2229

2330

2431
def _check_google_client_version():
25-
global BIGQUERY_INSTALLED_VERSION, SHOW_VERBOSE_DEPRECATION
32+
global BIGQUERY_INSTALLED_VERSION, SHOW_VERBOSE_DEPRECATION, SHOW_PRIVATE_KEY_DEPRECATION
2633

2734
try:
2835
import pkg_resources
@@ -53,6 +60,10 @@ def _check_google_client_version():
5360
SHOW_VERBOSE_DEPRECATION = (
5461
pandas_installed_version >= pandas_version_wo_verbosity
5562
)
63+
pandas_version_with_credentials_arg = pkg_resources.parse_version("0.24.0")
64+
SHOW_PRIVATE_KEY_DEPRECATION = (
65+
pandas_installed_version >= pandas_version_with_credentials_arg
66+
)
5667

5768

5869
def _test_google_api_imports():
@@ -805,6 +816,11 @@ def read_gbq(
805816
stacklevel=2,
806817
)
807818

819+
if private_key is not None and SHOW_PRIVATE_KEY_DEPRECATION:
820+
warnings.warn(
821+
PRIVATE_KEY_DEPRECATION_MESSAGE, FutureWarning, stacklevel=2
822+
)
823+
808824
if dialect not in ("legacy", "standard"):
809825
raise ValueError("'{0}' is not valid for dialect".format(dialect))
810826

@@ -969,6 +985,11 @@ def to_gbq(
969985
stacklevel=1,
970986
)
971987

988+
if private_key is not None and SHOW_PRIVATE_KEY_DEPRECATION:
989+
warnings.warn(
990+
PRIVATE_KEY_DEPRECATION_MESSAGE, FutureWarning, stacklevel=2
991+
)
992+
972993
if if_exists not in ("fail", "replace", "append"):
973994
raise ValueError("'{0}' is not valid for if_exists".format(if_exists))
974995

tests/unit/test_gbq.py

+93
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,57 @@ def test_to_gbq_with_verbose_old_pandas_no_warnings(recwarn, min_bq_version):
187187
assert len(recwarn) == 0
188188

189189

190+
def test_to_gbq_with_private_key_new_pandas_warns_deprecation(
191+
min_bq_version, monkeypatch
192+
):
193+
import pkg_resources
194+
from pandas_gbq import auth
195+
196+
monkeypatch.setattr(auth, "get_credentials", mock_get_credentials)
197+
198+
pandas_version = pkg_resources.parse_version("0.24.0")
199+
with pytest.warns(FutureWarning), mock.patch(
200+
"pkg_resources.Distribution.parsed_version",
201+
new_callable=mock.PropertyMock,
202+
) as mock_version:
203+
mock_version.side_effect = [min_bq_version, pandas_version]
204+
try:
205+
gbq.to_gbq(
206+
DataFrame([[1]]),
207+
"dataset.tablename",
208+
project_id="my-project",
209+
private_key="path/to/key.json",
210+
)
211+
except gbq.TableCreationError:
212+
pass
213+
214+
215+
def test_to_gbq_with_private_key_old_pandas_no_warnings(
216+
recwarn, min_bq_version, monkeypatch
217+
):
218+
import pkg_resources
219+
from pandas_gbq import auth
220+
221+
monkeypatch.setattr(auth, "get_credentials", mock_get_credentials)
222+
223+
pandas_version = pkg_resources.parse_version("0.23.4")
224+
with mock.patch(
225+
"pkg_resources.Distribution.parsed_version",
226+
new_callable=mock.PropertyMock,
227+
) as mock_version:
228+
mock_version.side_effect = [min_bq_version, pandas_version]
229+
try:
230+
gbq.to_gbq(
231+
DataFrame([[1]]),
232+
"dataset.tablename",
233+
project_id="my-project",
234+
private_key="path/to/key.json",
235+
)
236+
except gbq.TableCreationError:
237+
pass
238+
assert len(recwarn) == 0
239+
240+
190241
def test_to_gbq_doesnt_run_query(
191242
recwarn, mock_bigquery_client, min_bq_version
192243
):
@@ -334,6 +385,48 @@ def test_read_gbq_with_verbose_old_pandas_no_warnings(recwarn, min_bq_version):
334385
assert len(recwarn) == 0
335386

336387

388+
def test_read_gbq_with_private_key_new_pandas_warns_deprecation(
389+
min_bq_version, monkeypatch
390+
):
391+
import pkg_resources
392+
from pandas_gbq import auth
393+
394+
monkeypatch.setattr(auth, "get_credentials", mock_get_credentials)
395+
396+
pandas_version = pkg_resources.parse_version("0.24.0")
397+
with pytest.warns(FutureWarning), mock.patch(
398+
"pkg_resources.Distribution.parsed_version",
399+
new_callable=mock.PropertyMock,
400+
) as mock_version:
401+
mock_version.side_effect = [min_bq_version, pandas_version]
402+
gbq.read_gbq(
403+
"SELECT 1", project_id="my-project", private_key="path/to/key.json"
404+
)
405+
406+
407+
def test_read_gbq_with_private_key_old_pandas_no_warnings(
408+
recwarn, min_bq_version, monkeypatch
409+
):
410+
import pkg_resources
411+
from pandas_gbq import auth
412+
413+
monkeypatch.setattr(auth, "get_credentials", mock_get_credentials)
414+
415+
pandas_version = pkg_resources.parse_version("0.23.4")
416+
with mock.patch(
417+
"pkg_resources.Distribution.parsed_version",
418+
new_callable=mock.PropertyMock,
419+
) as mock_version:
420+
mock_version.side_effect = [min_bq_version, pandas_version]
421+
gbq.read_gbq(
422+
"SELECT 1",
423+
project_id="my-project",
424+
dialect="standard",
425+
private_key="path/to/key.json",
426+
)
427+
assert len(recwarn) == 0
428+
429+
337430
def test_read_gbq_with_invalid_dialect():
338431
with pytest.raises(ValueError) as excinfo:
339432
gbq.read_gbq("SELECT 1", dialect="invalid")

0 commit comments

Comments
 (0)