Repository: pandas-dev/pandas

Issue:
Exception when calling read_gbq : No module named discovery
I ran into the following exception when using the pandas `read_gbq()` function.

```
      1 import pandas as pd
----> 2 pd.read_gbq('select * from SampleDataset.SampleTable', project_id='xxxxxxx')

/usr/local/lib/python2.7/dist-packages/pandas/io/gbq.pyc in read_gbq(query, project_id, index_col, col_order, reauth, verbose)
    425         job_id = uuid.uuid4().hex
    426         rows = []
--> 427         remaining_rows = len(dataframe)
    428 
    429         if self.verbose:

/usr/local/lib/python2.7/dist-packages/pandas/io/gbq.pyc in __init__(self, project_id, reauth)
    111     not match the schema of the destination
    112     table in BigQuery.
--> 113     """
    114     pass
    115 

/usr/local/lib/python2.7/dist-packages/pandas/io/gbq.pyc in test_google_api_imports(self)
    127     Raised when BigQuery reports a streaming insert error.
    128     For more information see `Streaming Data Into BigQuery
--> 129     <https://cloud.google.com/bigquery/streaming-data-into-bigquery>`__
    130     """
    131 

ImportError: Missing module required for Google BigQuery support: No module named discovery
```

An exception occurs in `test_google_api_imports()` . I believe the issue is on line 49 in https://github.com/pydata/pandas/blob/master/pandas/io/gbq.py . 

We use

```
from apiclient.discovery import build
```

instead of

```
from googleapiclient.discovery import build
```

`apiclient` is an alias for `googleapiclient` according to https://github.com/google/google-api-python-client/blob/master/apiclient/__init__.py#L1

A similar issue is reported here: https://github.com/google/google-api-python-client/issues/13

`apiclient.__version__` fails

```
>> import apiclient
>> apiclient.__version__
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-90-662a0f56e34b> in <module>()
      1 import apiclient
----> 2 apiclient.__version__

AttributeError: 'module' object has no attribute '__version__'
```

`googleapiclient.__version__` works

```
import googleapiclient
googleapiclient.__version__
```

```

INSTALLED VERSIONS
------------------
commit: None
python: 2.7.9.final.0
python-bits: 64
OS: Linux
OS-release: 3.16.0-4-amd64
machine: x86_64
processor: 
byteorder: little
LC_ALL: None
LANG: None

pandas: None
nose: 1.3.7
pip: 1.5.6
setuptools: 5.5.1
Cython: 0.24
numpy: 1.10.4
scipy: 0.17.0
statsmodels: 0.6.1
IPython: 4.0.3
sphinx: None
patsy: 0.4.1
dateutil: 2.4.2
pytz: 2015.7
blosc: None
bottleneck: None
tables: None
numexpr: None
matplotlib: 1.5.1
openpyxl: None
xlrd: None
xlwt: None
xlsxwriter: None
lxml: None
bs4: None
html5lib: 0.999
httplib2: 0.9.2
apiclient: 1.5.1
sqlalchemy: None
pymysql: None
psycopg2: None
Jinja2: None
```



Discussion:
I will submit a PR


Resolving patch:
diff --git a/pandas/io/gbq.py b/pandas/io/gbq.py
--- a/pandas/io/gbq.py
+++ b/pandas/io/gbq.py
@@ -46,8 +46,12 @@ def _test_google_api_imports():
 
     try:
         import httplib2  # noqa
-        from apiclient.discovery import build  # noqa
-        from apiclient.errors import HttpError  # noqa
+        try:
+            from googleapiclient.discovery import build  # noqa
+            from googleapiclient.errors import HttpError  # noqa
+        except:
+            from apiclient.discovery import build  # noqa
+            from apiclient.errors import HttpError  # noqa
         from oauth2client.client import AccessTokenRefreshError  # noqa
         from oauth2client.client import OAuth2WebServerFlow  # noqa
         from oauth2client.file import Storage  # noqa
@@ -266,7 +270,10 @@ def sizeof_fmt(num, suffix='b'):
 
     def get_service(self):
         import httplib2
-        from apiclient.discovery import build
+        try:
+            from googleapiclient.discovery import build
+        except:
+            from apiclient.discovery import build
 
         http = httplib2.Http()
         http = self.credentials.authorize(http)
@@ -315,7 +322,10 @@ def process_insert_errors(self, insert_errors):
         raise StreamingInsertError
 
     def run_query(self, query):
-        from apiclient.errors import HttpError
+        try:
+            from googleapiclient.errors import HttpError
+        except:
+            from apiclient.errors import HttpError
         from oauth2client.client import AccessTokenRefreshError
 
         _check_google_client_version()
@@ -420,7 +430,10 @@ def run_query(self, query):
         return schema, result_pages
 
     def load_data(self, dataframe, dataset_id, table_id, chunksize):
-        from apiclient.errors import HttpError
+        try:
+            from googleapiclient.errors import HttpError
+        except:
+            from apiclient.errors import HttpError
 
         job_id = uuid.uuid4().hex
         rows = []
@@ -474,7 +487,10 @@ def load_data(self, dataframe, dataset_id, table_id, chunksize):
         self._print("\n")
 
     def verify_schema(self, dataset_id, table_id, schema):
-        from apiclient.errors import HttpError
+        try:
+            from googleapiclient.errors import HttpError
+        except:
+            from apiclient.errors import HttpError
 
         try:
             return (self.service.tables().get(
@@ -765,7 +781,10 @@ class _Table(GbqConnector):
 
     def __init__(self, project_id, dataset_id, reauth=False, verbose=False,
                  private_key=None):
-        from apiclient.errors import HttpError
+        try:
+            from googleapiclient.errors import HttpError
+        except:
+            from apiclient.errors import HttpError
         self.http_error = HttpError
         self.dataset_id = dataset_id
         super(_Table, self).__init__(project_id, reauth, verbose, private_key)
@@ -865,7 +884,10 @@ class _Dataset(GbqConnector):
 
     def __init__(self, project_id, reauth=False, verbose=False,
                  private_key=None):
-        from apiclient.errors import HttpError
+        try:
+            from googleapiclient.errors import HttpError
+        except:
+            from apiclient.errors import HttpError
         self.http_error = HttpError
         super(_Dataset, self).__init__(project_id, reauth, verbose,
                                        private_key)


Test patch:
diff --git a/pandas/io/tests/test_gbq.py b/pandas/io/tests/test_gbq.py
--- a/pandas/io/tests/test_gbq.py
+++ b/pandas/io/tests/test_gbq.py
@@ -73,8 +73,12 @@ def _test_imports():
 
     if _SETUPTOOLS_INSTALLED:
         try:
-            from apiclient.discovery import build  # noqa
-            from apiclient.errors import HttpError  # noqa
+            try:
+                from googleapiclient.discovery import build  # noqa
+                from googleapiclient.errors import HttpError  # noqa
+            except:
+                from apiclient.discovery import build  # noqa
+                from apiclient.errors import HttpError  # noqa
 
             from oauth2client.client import OAuth2WebServerFlow  # noqa
             from oauth2client.client import AccessTokenRefreshError  # noqa
@@ -280,6 +284,17 @@ class GBQUnitTests(tm.TestCase):
     def setUp(self):
         test_requirements()
 
+    def test_import_google_api_python_client(self):
+        if compat.PY2:
+            with tm.assertRaises(ImportError):
+                from googleapiclient.discovery import build  # noqa
+                from googleapiclient.errors import HttpError  # noqa
+            from apiclient.discovery import build  # noqa
+            from apiclient.errors import HttpError  # noqa
+        else:
+            from googleapiclient.discovery import build  # noqa
+            from googleapiclient.errors import HttpError  # noqa
+
     def test_should_return_bigquery_integers_as_python_floats(self):
         result = gbq._parse_entry(1, 'INTEGER')
         tm.assert_equal(result, float(1))