Skip to content

ENH: deprecate private_key argument #240

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

Merged
merged 1 commit into from
Dec 20, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 8 additions & 2 deletions docs/source/howto/authentication.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ To use service account credentials, set the ``credentials`` parameter to the res

.. code:: python

credentials = google.oauth2.service_account.Credentials.from_service_account_file(
from google.oauth2 import service_account
import pandas_gbq

credentials = service_account.Credentials.from_service_account_file(
'path/to/key.json',
)
df = pandas_gbq.read_gbq(sql, project_id="YOUR-PROJECT-ID", credentials=credentials)
Expand All @@ -35,7 +38,10 @@ To use service account credentials, set the ``credentials`` parameter to the res

.. code:: python

credentials = google.oauth2.service_account.Credentials.from_service_account_info(
from google.oauth2 import service_account
import pandas_gbq

credentials = service_account.Credentials.from_service_account_info(
{
"type": "service_account",
"project_id": "YOUR-PROJECT-ID",
Expand Down
23 changes: 22 additions & 1 deletion pandas_gbq/gbq.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@

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

try:
import tqdm # noqa
Expand All @@ -22,7 +29,7 @@


def _check_google_client_version():
global BIGQUERY_INSTALLED_VERSION, SHOW_VERBOSE_DEPRECATION
global BIGQUERY_INSTALLED_VERSION, SHOW_VERBOSE_DEPRECATION, SHOW_PRIVATE_KEY_DEPRECATION

try:
import pkg_resources
Expand Down Expand Up @@ -53,6 +60,10 @@ def _check_google_client_version():
SHOW_VERBOSE_DEPRECATION = (
pandas_installed_version >= pandas_version_wo_verbosity
)
pandas_version_with_credentials_arg = pkg_resources.parse_version("0.24.0")
SHOW_PRIVATE_KEY_DEPRECATION = (
pandas_installed_version >= pandas_version_with_credentials_arg
)


def _test_google_api_imports():
Expand Down Expand Up @@ -805,6 +816,11 @@ def read_gbq(
stacklevel=2,
)

if private_key is not None and SHOW_PRIVATE_KEY_DEPRECATION:
warnings.warn(
PRIVATE_KEY_DEPRECATION_MESSAGE, FutureWarning, stacklevel=2
)

if dialect not in ("legacy", "standard"):
raise ValueError("'{0}' is not valid for dialect".format(dialect))

Expand Down Expand Up @@ -969,6 +985,11 @@ def to_gbq(
stacklevel=1,
)

if private_key is not None and SHOW_PRIVATE_KEY_DEPRECATION:
warnings.warn(
PRIVATE_KEY_DEPRECATION_MESSAGE, FutureWarning, stacklevel=2
)

if if_exists not in ("fail", "replace", "append"):
raise ValueError("'{0}' is not valid for if_exists".format(if_exists))

Expand Down
93 changes: 93 additions & 0 deletions tests/unit/test_gbq.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,57 @@ def test_to_gbq_with_verbose_old_pandas_no_warnings(recwarn, min_bq_version):
assert len(recwarn) == 0


def test_to_gbq_with_private_key_new_pandas_warns_deprecation(
min_bq_version, monkeypatch
):
import pkg_resources
from pandas_gbq import auth

monkeypatch.setattr(auth, "get_credentials", mock_get_credentials)

pandas_version = pkg_resources.parse_version("0.24.0")
with pytest.warns(FutureWarning), mock.patch(
"pkg_resources.Distribution.parsed_version",
new_callable=mock.PropertyMock,
) as mock_version:
mock_version.side_effect = [min_bq_version, pandas_version]
try:
gbq.to_gbq(
DataFrame([[1]]),
"dataset.tablename",
project_id="my-project",
private_key="path/to/key.json",
)
except gbq.TableCreationError:
pass


def test_to_gbq_with_private_key_old_pandas_no_warnings(
recwarn, min_bq_version, monkeypatch
):
import pkg_resources
from pandas_gbq import auth

monkeypatch.setattr(auth, "get_credentials", mock_get_credentials)

pandas_version = pkg_resources.parse_version("0.23.4")
with mock.patch(
"pkg_resources.Distribution.parsed_version",
new_callable=mock.PropertyMock,
) as mock_version:
mock_version.side_effect = [min_bq_version, pandas_version]
try:
gbq.to_gbq(
DataFrame([[1]]),
"dataset.tablename",
project_id="my-project",
private_key="path/to/key.json",
)
except gbq.TableCreationError:
pass
assert len(recwarn) == 0


def test_to_gbq_doesnt_run_query(
recwarn, mock_bigquery_client, min_bq_version
):
Expand Down Expand Up @@ -334,6 +385,48 @@ def test_read_gbq_with_verbose_old_pandas_no_warnings(recwarn, min_bq_version):
assert len(recwarn) == 0


def test_read_gbq_with_private_key_new_pandas_warns_deprecation(
min_bq_version, monkeypatch
):
import pkg_resources
from pandas_gbq import auth

monkeypatch.setattr(auth, "get_credentials", mock_get_credentials)

pandas_version = pkg_resources.parse_version("0.24.0")
with pytest.warns(FutureWarning), mock.patch(
"pkg_resources.Distribution.parsed_version",
new_callable=mock.PropertyMock,
) as mock_version:
mock_version.side_effect = [min_bq_version, pandas_version]
gbq.read_gbq(
"SELECT 1", project_id="my-project", private_key="path/to/key.json"
)


def test_read_gbq_with_private_key_old_pandas_no_warnings(
recwarn, min_bq_version, monkeypatch
):
import pkg_resources
from pandas_gbq import auth

monkeypatch.setattr(auth, "get_credentials", mock_get_credentials)

pandas_version = pkg_resources.parse_version("0.23.4")
with mock.patch(
"pkg_resources.Distribution.parsed_version",
new_callable=mock.PropertyMock,
) as mock_version:
mock_version.side_effect = [min_bq_version, pandas_version]
gbq.read_gbq(
"SELECT 1",
project_id="my-project",
dialect="standard",
private_key="path/to/key.json",
)
assert len(recwarn) == 0


def test_read_gbq_with_invalid_dialect():
with pytest.raises(ValueError) as excinfo:
gbq.read_gbq("SELECT 1", dialect="invalid")
Expand Down