diff --git a/ci/requirements-2.7.pip b/ci/requirements-2.7.pip
index 9bc533110cea3..54596ad2a8169 100644
--- a/ci/requirements-2.7.pip
+++ b/ci/requirements-2.7.pip
@@ -2,5 +2,6 @@ blosc
httplib2
google-api-python-client == 1.2
python-gflags == 2.0
+oauth2client == 1.5.0
pathlib
py
diff --git a/ci/requirements-3.4.pip b/ci/requirements-3.4.pip
index 62be867437af1..55986a0220bf0 100644
--- a/ci/requirements-3.4.pip
+++ b/ci/requirements-3.4.pip
@@ -2,3 +2,4 @@ python-dateutil==2.2
blosc
httplib2
google-api-python-client
+oauth2client
diff --git a/doc/source/install.rst b/doc/source/install.rst
index 11b9115aa9c81..c1950ee7bf76c 100644
--- a/doc/source/install.rst
+++ b/doc/source/install.rst
@@ -267,9 +267,11 @@ Optional Dependencies
`__, or `xclip
`__: necessary to use
:func:`~pandas.io.clipboard.read_clipboard`. Most package managers on Linux distributions will have ``xclip`` and/or ``xsel`` immediately available for installation.
-* Google's `python-gflags `__
- and `google-api-python-client `__: Needed for :mod:`~pandas.io.gbq`
-* `httplib2 `__: Needed for :mod:`~pandas.io.gbq`
+* Google's `python-gflags `__ ,
+ `oauth2client `__ ,
+ `httplib2 `__
+ and `google-api-python-client `__
+ : Needed for :mod:`~pandas.io.gbq`
* One of the following combinations of libraries is needed to use the
top-level :func:`~pandas.io.html.read_html` function:
diff --git a/doc/source/whatsnew/v0.18.0.txt b/doc/source/whatsnew/v0.18.0.txt
index 90ded17286c9f..acd9533165c6d 100644
--- a/doc/source/whatsnew/v0.18.0.txt
+++ b/doc/source/whatsnew/v0.18.0.txt
@@ -1271,3 +1271,4 @@ Bug Fixes
- Bug when specifying a UTC ``DatetimeIndex`` by setting ``utc=True`` in ``.to_datetime`` (:issue:`11934`)
- Bug when increasing the buffer size of CSV reader in ``read_csv`` (:issue:`12494`)
- Bug when setting columns of a ``DataFrame`` with duplicate column names (:issue:`12344`)
+- Resolve ImportError in ``read_gbq`` which appears with oauthclient >= 2.0.0 (:issue:`12572`)
diff --git a/pandas/io/gbq.py b/pandas/io/gbq.py
index c7481a953e47b..e706434f29dc5 100644
--- a/pandas/io/gbq.py
+++ b/pandas/io/gbq.py
@@ -50,7 +50,6 @@ def _test_google_api_imports():
from apiclient.errors import HttpError # noqa
from oauth2client.client import AccessTokenRefreshError # noqa
from oauth2client.client import OAuth2WebServerFlow # noqa
- from oauth2client.client import SignedJwtAssertionCredentials # noqa
from oauth2client.file import Storage # noqa
from oauth2client.tools import run_flow, argparser # noqa
except ImportError as e:
@@ -179,7 +178,30 @@ def get_user_account_credentials(self):
return credentials
def get_service_account_credentials(self):
- from oauth2client.client import SignedJwtAssertionCredentials
+ # Bug fix for https://github.com/pydata/pandas/issues/12572
+ # We need to know that a supported version of oauth2client is installed
+ # Test that either of the following is installed:
+ # - SignedJwtAssertionCredentials from oauth2client.client
+ # - ServiceAccountCredentials from oauth2client.service_account
+ # SignedJwtAssertionCredentials is available in oauthclient < 2.0.0
+ # ServiceAccountCredentials is available in oauthclient >= 2.0.0
+ oauth2client_v1 = True
+ oauth2client_v2 = True
+
+ try:
+ from oauth2client.client import SignedJwtAssertionCredentials
+ except ImportError:
+ oauth2client_v1 = False
+
+ try:
+ from oauth2client.service_account import ServiceAccountCredentials
+ except ImportError:
+ oauth2client_v2 = False
+
+ if not oauth2client_v1 and not oauth2client_v2:
+ raise ImportError("Missing oauth2client required for BigQuery "
+ "service account support")
+
from os.path import isfile
try:
@@ -197,11 +219,16 @@ def get_service_account_credentials(self):
json_key['private_key'] = bytes(
json_key['private_key'], 'UTF-8')
- return SignedJwtAssertionCredentials(
- json_key['client_email'],
- json_key['private_key'],
- self.scope,
- )
+ if oauth2client_v1:
+ return SignedJwtAssertionCredentials(
+ json_key['client_email'],
+ json_key['private_key'],
+ self.scope,
+ )
+ else:
+ return ServiceAccountCredentials.from_json_keyfile_dict(
+ json_key,
+ self.scope)
except (KeyError, ValueError, TypeError, AttributeError):
raise InvalidPrivateKeyFormat(
"Private key is missing or invalid. It should be service "
diff --git a/pandas/io/tests/test_gbq.py b/pandas/io/tests/test_gbq.py
index 5a1c2d63af365..865b7e8d689c0 100644
--- a/pandas/io/tests/test_gbq.py
+++ b/pandas/io/tests/test_gbq.py
@@ -77,7 +77,6 @@ def _test_imports():
from oauth2client.client import OAuth2WebServerFlow # noqa
from oauth2client.client import AccessTokenRefreshError # noqa
- from oauth2client.client import SignedJwtAssertionCredentials # noqa
from oauth2client.file import Storage # noqa
from oauth2client.tools import run_flow # noqa
@@ -115,6 +114,30 @@ def _test_imports():
raise ImportError(
"pandas requires httplib2 for Google BigQuery support")
+ # Bug fix for https://github.com/pydata/pandas/issues/12572
+ # We need to know that a supported version of oauth2client is installed
+ # Test that either of the following is installed:
+ # - SignedJwtAssertionCredentials from oauth2client.client
+ # - ServiceAccountCredentials from oauth2client.service_account
+ # SignedJwtAssertionCredentials is available in oauthclient < 2.0.0
+ # ServiceAccountCredentials is available in oauthclient >= 2.0.0
+ oauth2client_v1 = True
+ oauth2client_v2 = True
+
+ try:
+ from oauth2client.client import SignedJwtAssertionCredentials # noqa
+ except ImportError:
+ oauth2client_v1 = False
+
+ try:
+ from oauth2client.service_account import ServiceAccountCredentials # noqa
+ except ImportError:
+ oauth2client_v2 = False
+
+ if not oauth2client_v1 and not oauth2client_v2:
+ raise ImportError("Missing oauth2client required for BigQuery "
+ "service account support")
+
def test_requirements():
try: