diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst index 0f1d6e1b..fb841b34 100644 --- a/docs/source/changelog.rst +++ b/docs/source/changelog.rst @@ -5,6 +5,8 @@ Changelog ------------------ - :func:`read_gbq` now raises ``QueryTimeout`` if the request exceeds the ``query.timeoutMs`` value specified in the BigQuery configuration. (:issue:`76`) +- Environment variable ``PANDAS_GBQ_CREDENTIALS_FILE`` can now be used to override the default location where the BigQuery user account credentials are stored. (:issue:`86`) + 0.2.0 / 2017-07-24 ------------------ diff --git a/pandas_gbq/gbq.py b/pandas_gbq/gbq.py index 0c538662..d871c068 100644 --- a/pandas_gbq/gbq.py +++ b/pandas_gbq/gbq.py @@ -5,6 +5,7 @@ import uuid import time import sys +import os import numpy as np @@ -279,7 +280,7 @@ def load_user_account_credentials(self): from google.oauth2.credentials import Credentials try: - with open('bigquery_credentials.dat') as credentials_file: + with open(_get_credentials_file()) as credentials_file: credentials_json = json.load(credentials_file) except (IOError, ValueError): return None @@ -307,7 +308,7 @@ def save_user_account_credentials(self, credentials): .. versionadded 0.2.0 """ try: - with open('bigquery_credentials.dat', 'w') as credentials_file: + with open(_get_credentials_file(), 'w') as credentials_file: credentials_json = { 'refresh_token': credentials.refresh_token, 'id_token': credentials.id_token, @@ -790,6 +791,11 @@ def delete_and_recreate_table(self, dataset_id, table_id, table_schema): sleep(delay) +def _get_credentials_file(): + return os.environ.get( + 'PANDAS_GBQ_CREDENTIALS_FILE', 'bigquery_credentials.dat') + + def _parse_data(schema, rows): # see: # http://pandas.pydata.org/pandas-docs/dev/missing_data.html @@ -875,7 +881,10 @@ def read_gbq(query, project_id=None, index_col=None, col_order=None, authentication (eg. jupyter iPython notebook on remote host) auth_local_webserver : boolean, default False Use the [local webserver flow] instead of the [console flow] when - getting user credentials. + getting user credentials. A file named bigquery_credentials.dat will + be created in current dir. You can also set PANDAS_GBQ_CREDENTIALS_FILE + environment variable so as to define a specific path to store this + credential (eg. /etc/keys/bigquery.dat). .. [local webserver flow] http://google-auth-oauthlib.readthedocs.io/en/latest/reference/google_auth_oauthlib.flow.html#google_auth_oauthlib.flow.InstalledAppFlow.run_local_server diff --git a/pandas_gbq/tests/test_gbq.py b/pandas_gbq/tests/test_gbq.py index c9ac31dd..f61e4b52 100644 --- a/pandas_gbq/tests/test_gbq.py +++ b/pandas_gbq/tests/test_gbq.py @@ -321,6 +321,14 @@ def test_import_google_api_python_client(self): from googleapiclient.discovery import build # noqa from googleapiclient.errors import HttpError # noqa + def test_should_return_credentials_path_set_by_env_var(self): + import mock + env = {'PANDAS_GBQ_CREDENTIALS_FILE': '/tmp/dummy.dat'} + with mock.patch.dict('os.environ', env): + assert gbq._get_credentials_file() == '/tmp/dummy.dat' + + assert gbq._get_credentials_file() == 'bigquery_credentials.dat' + def test_should_return_bigquery_integers_as_python_ints(self): result = gbq._parse_entry(1, 'INTEGER') assert result == int(1)