Skip to content

Commit 2cf4132

Browse files
Chris Grinoldsjreback
Chris Grinolds
authored andcommitted
Updates to Google BigQuery connector (#9713, #8327)
commit 3d6fdc8751134f6e5bac700519358cf9a700aba1 Author: Chris Grinolds <[email protected]> Date: Wed Apr 29 21:43:10 2015 -0700 Added missing imports that caused tests to fail commit 6c345d8dbc0c36bd4369dd220eceb495ab5ff2c6 Author: Chris Grinolds <[email protected]> Date: Wed Apr 29 16:23:01 2015 -0700 Updated test suite to handle changes to gbq.py commit f43e65f924d07f88bbbe308b9ea396b1f2a720f9 Author: Chris Grinolds <[email protected]> Date: Wed Apr 29 08:46:00 2015 -0700 Updated BigQuery connector to no longer use deprecated ```oauth2client.tools.run() (#8327) commit ea92e200ff341a3025b06868a565b1eea506c4c2 Author: Chris Grinolds <[email protected]> Date: Wed Apr 29 08:43:43 2015 -0700 Import BigQuery dependencies on a per-method basis (#9713)
1 parent f2717fc commit 2cf4132

File tree

3 files changed

+112
-100
lines changed

3 files changed

+112
-100
lines changed

doc/source/whatsnew/v0.16.1.txt

+2
Original file line numberDiff line numberDiff line change
@@ -297,3 +297,5 @@ Bug Fixes
297297
- Bug in hiding ticklabels with subplots and shared axes when adding a new plot to an existing grid of axes (:issue:`9158`)
298298
- Bug in ``transform`` and ``filter`` when grouping on a categorical variable (:issue:`9921`)
299299
- Bug in ``transform`` when groups are equal in number and dtype to the input index (:issue:`9700`)
300+
- Google BigQuery connector now imports dependencies on a per-method basis.(:issue:`9713`)
301+
- Updated BigQuery connector to no longer use deprecated ``oauth2client.tools.run()`` (:issue:`8327`)

pandas/io/gbq.py

+45-99
Original file line numberDiff line numberDiff line change
@@ -13,75 +13,22 @@
1313
from pandas.tools.merge import concat
1414
from pandas.core.common import PandasError
1515

16-
_IMPORTS = False
17-
_GOOGLE_API_CLIENT_INSTALLED = False
18-
_GOOGLE_API_CLIENT_VALID_VERSION = False
19-
_GOOGLE_FLAGS_INSTALLED = False
20-
_GOOGLE_FLAGS_VALID_VERSION = False
21-
_HTTPLIB2_INSTALLED = False
22-
_SETUPTOOLS_INSTALLED = False
2316

24-
def _importers():
25-
# import things we need
26-
# but make this done on a first use basis
27-
28-
global _IMPORTS
29-
if _IMPORTS:
30-
return
31-
32-
_IMPORTS = True
33-
34-
if not compat.PY3:
35-
36-
global _GOOGLE_API_CLIENT_INSTALLED, _GOOGLE_API_CLIENT_VALID_VERSION, \
37-
_GOOGLE_FLAGS_INSTALLED, _GOOGLE_FLAGS_VALID_VERSION, \
38-
_HTTPLIB2_INSTALLED, _SETUPTOOLS_INSTALLED
39-
40-
try:
41-
import pkg_resources
42-
_SETUPTOOLS_INSTALLED = True
43-
except ImportError:
44-
_SETUPTOOLS_INSTALLED = False
45-
46-
if _SETUPTOOLS_INSTALLED:
47-
try:
48-
from apiclient.discovery import build
49-
from apiclient.http import MediaFileUpload
50-
from apiclient.errors import HttpError
51-
52-
from oauth2client.client import OAuth2WebServerFlow
53-
from oauth2client.client import AccessTokenRefreshError
54-
from oauth2client.client import flow_from_clientsecrets
55-
from oauth2client.file import Storage
56-
from oauth2client.tools import run
57-
_GOOGLE_API_CLIENT_INSTALLED=True
58-
_GOOGLE_API_CLIENT_VERSION = pkg_resources.get_distribution('google-api-python-client').version
59-
60-
if LooseVersion(_GOOGLE_API_CLIENT_VERSION) >= '1.2.0':
61-
_GOOGLE_API_CLIENT_VALID_VERSION = True
62-
63-
except ImportError:
64-
_GOOGLE_API_CLIENT_INSTALLED = False
65-
66-
67-
try:
68-
import gflags as flags
69-
_GOOGLE_FLAGS_INSTALLED = True
70-
71-
_GOOGLE_FLAGS_VERSION = pkg_resources.get_distribution('python-gflags').version
17+
def _check_google_client_version():
18+
if compat.PY3:
19+
raise NotImplementedError("Google's libraries do not support Python 3 yet")
7220

73-
if LooseVersion(_GOOGLE_FLAGS_VERSION) >= '2.0':
74-
_GOOGLE_FLAGS_VALID_VERSION = True
21+
try:
22+
import pkg_resources
7523

76-
except ImportError:
77-
_GOOGLE_FLAGS_INSTALLED = False
24+
except ImportError:
25+
raise ImportError('Could not import pkg_resources (setuptools).')
7826

79-
try:
80-
import httplib2
81-
_HTTPLIB2_INSTALLED = True
82-
except ImportError:
83-
_HTTPLIB2_INSTALLED = False
27+
_GOOGLE_API_CLIENT_VERSION = pkg_resources.get_distribution('google-api-python-client').version
8428

29+
if LooseVersion(_GOOGLE_API_CLIENT_VERSION) < '1.2.0':
30+
raise ImportError("pandas requires google-api-python-client >= 1.2.0 for Google "
31+
"BigQuery support, current version " + _GOOGLE_API_CLIENT_VERSION)
8532

8633
logger = logging.getLogger('pandas.io.gbq')
8734
logger.setLevel(logging.ERROR)
@@ -142,6 +89,16 @@ def __init__(self, project_id, reauth=False):
14289
self.service = self.get_service(self.credentials)
14390

14491
def get_credentials(self):
92+
try:
93+
from oauth2client.client import OAuth2WebServerFlow
94+
from oauth2client.file import Storage
95+
from oauth2client.tools import run_flow, argparser
96+
97+
except ImportError:
98+
raise ImportError('Could not import Google API Client.')
99+
100+
_check_google_client_version()
101+
145102
flow = OAuth2WebServerFlow(client_id='495642085510-k0tmvj2m941jhre2nbqka17vqpjfddtd.apps.googleusercontent.com',
146103
client_secret='kOc9wMptUtxkcIFbtZCcrEAc',
147104
scope='https://www.googleapis.com/auth/bigquery',
@@ -151,18 +108,41 @@ def get_credentials(self):
151108
credentials = storage.get()
152109

153110
if credentials is None or credentials.invalid or self.reauth:
154-
credentials = run(flow, storage)
111+
credentials = run_flow(flow, storage, argparser.parse_args([]))
155112

156113
return credentials
157114

158115
def get_service(self, credentials):
116+
try:
117+
import httplib2
118+
119+
except ImportError:
120+
raise ImportError("pandas requires httplib2 for Google BigQuery support")
121+
122+
try:
123+
from apiclient.discovery import build
124+
125+
except ImportError:
126+
raise ImportError('Could not import Google API Client.')
127+
128+
_check_google_client_version()
129+
159130
http = httplib2.Http()
160131
http = credentials.authorize(http)
161132
bigquery_service = build('bigquery', 'v2', http=http)
162133

163134
return bigquery_service
164135

165136
def run_query(self, query):
137+
try:
138+
from apiclient.errors import HttpError
139+
from oauth2client.client import AccessTokenRefreshError
140+
141+
except ImportError:
142+
raise ImportError('Could not import Google API Client.')
143+
144+
_check_google_client_version()
145+
166146
job_collection = self.service.jobs()
167147
job_data = {
168148
'configuration': {
@@ -313,38 +293,6 @@ def _parse_entry(field_value, field_type):
313293
return field_value == 'true'
314294
return field_value
315295

316-
def _test_imports():
317-
318-
_importers()
319-
_GOOGLE_API_CLIENT_INSTALLED
320-
_GOOGLE_API_CLIENT_VALID_VERSION
321-
_GOOGLE_FLAGS_INSTALLED
322-
_GOOGLE_FLAGS_VALID_VERSION
323-
_HTTPLIB2_INSTALLED
324-
_SETUPTOOLS_INSTALLED
325-
326-
if compat.PY3:
327-
raise NotImplementedError("Google's libraries do not support Python 3 yet")
328-
329-
if not _SETUPTOOLS_INSTALLED:
330-
raise ImportError('Could not import pkg_resources (setuptools).')
331-
332-
if not _GOOGLE_API_CLIENT_INSTALLED:
333-
raise ImportError('Could not import Google API Client.')
334-
335-
if not _GOOGLE_FLAGS_INSTALLED:
336-
raise ImportError('Could not import Google Command Line Flags Module.')
337-
338-
if not _GOOGLE_API_CLIENT_VALID_VERSION:
339-
raise ImportError("pandas requires google-api-python-client >= 1.2.0 for Google "
340-
"BigQuery support, current version " + _GOOGLE_API_CLIENT_VERSION)
341-
342-
if not _GOOGLE_FLAGS_VALID_VERSION:
343-
raise ImportError("pandas requires python-gflags >= 2.0.0 for Google "
344-
"BigQuery support, current version " + _GOOGLE_FLAGS_VERSION)
345-
346-
if not _HTTPLIB2_INSTALLED:
347-
raise ImportError("pandas requires httplib2 for Google BigQuery support")
348296

349297
def read_gbq(query, project_id = None, index_col=None, col_order=None, reauth=False):
350298
"""Load data from Google BigQuery.
@@ -379,7 +327,6 @@ def read_gbq(query, project_id = None, index_col=None, col_order=None, reauth=Fa
379327
380328
"""
381329

382-
_test_imports()
383330

384331
if not project_id:
385332
raise TypeError("Missing required parameter: project_id")
@@ -450,7 +397,6 @@ def to_gbq(dataframe, destination_table, project_id=None, chunksize=10000,
450397
if multiple accounts are used.
451398
452399
"""
453-
_test_imports()
454400

455401
if not project_id:
456402
raise TypeError("Missing required parameter: project_id")

pandas/io/tests/test_gbq.py

+65-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212

1313
import numpy as np
1414

15+
from distutils.version import LooseVersion
16+
from pandas import compat
17+
1518
from pandas import NaT
1619
from pandas.compat import u
1720
from pandas.core.frame import DataFrame
@@ -22,16 +25,77 @@
2225

2326
VERSION = platform.python_version()
2427

28+
_IMPORTS = False
29+
_GOOGLE_API_CLIENT_INSTALLED = False
30+
_GOOGLE_API_CLIENT_VALID_VERSION = False
31+
_HTTPLIB2_INSTALLED = False
32+
_SETUPTOOLS_INSTALLED = False
33+
2534
def missing_bq():
2635
try:
2736
subprocess.call('bq')
2837
return False
2938
except OSError:
3039
return True
3140

41+
def _test_imports():
42+
if not compat.PY3:
43+
44+
global _GOOGLE_API_CLIENT_INSTALLED, _GOOGLE_API_CLIENT_VALID_VERSION, \
45+
_HTTPLIB2_INSTALLED, _SETUPTOOLS_INSTALLED
46+
47+
try:
48+
import pkg_resources
49+
_SETUPTOOLS_INSTALLED = True
50+
except ImportError:
51+
_SETUPTOOLS_INSTALLED = False
52+
53+
if _SETUPTOOLS_INSTALLED:
54+
try:
55+
from apiclient.discovery import build
56+
from apiclient.errors import HttpError
57+
58+
from oauth2client.client import OAuth2WebServerFlow
59+
from oauth2client.client import AccessTokenRefreshError
60+
61+
from oauth2client.file import Storage
62+
from oauth2client.tools import run_flow
63+
_GOOGLE_API_CLIENT_INSTALLED=True
64+
_GOOGLE_API_CLIENT_VERSION = pkg_resources.get_distribution('google-api-python-client').version
65+
66+
if LooseVersion(_GOOGLE_API_CLIENT_VERSION) >= '1.2.0':
67+
_GOOGLE_API_CLIENT_VALID_VERSION = True
68+
69+
except ImportError:
70+
_GOOGLE_API_CLIENT_INSTALLED = False
71+
72+
73+
try:
74+
import httplib2
75+
_HTTPLIB2_INSTALLED = True
76+
except ImportError:
77+
_HTTPLIB2_INSTALLED = False
78+
79+
80+
if compat.PY3:
81+
raise NotImplementedError("Google's libraries do not support Python 3 yet")
82+
83+
if not _SETUPTOOLS_INSTALLED:
84+
raise ImportError('Could not import pkg_resources (setuptools).')
85+
86+
if not _GOOGLE_API_CLIENT_INSTALLED:
87+
raise ImportError('Could not import Google API Client.')
88+
89+
if not _GOOGLE_API_CLIENT_VALID_VERSION:
90+
raise ImportError("pandas requires google-api-python-client >= 1.2.0 for Google "
91+
"BigQuery support, current version " + _GOOGLE_API_CLIENT_VERSION)
92+
93+
if not _HTTPLIB2_INSTALLED:
94+
raise ImportError("pandas requires httplib2 for Google BigQuery support")
95+
3296
def test_requirements():
3397
try:
34-
gbq._test_imports()
98+
_test_imports()
3599
except (ImportError, NotImplementedError) as import_exception:
36100
raise nose.SkipTest(import_exception)
37101

0 commit comments

Comments
 (0)