diff --git a/.gitignore b/.gitignore index dd8bffdf608b..850c3a9fab06 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ coverage.xml python-docs-samples.json service-account.json +client-secrets.json __pycache__ *db\.sqlite3 managed_vms/django_tutorial/static/* @@ -16,3 +17,4 @@ testing/resources/client-secrets.json secrets.tar .cache junit.xml +credentials.dat diff --git a/bigquery/api/installed_app.py b/bigquery/api/installed_app.py new file mode 100644 index 000000000000..4bbc13a0010b --- /dev/null +++ b/bigquery/api/installed_app.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python + +# Copyright 2015, Google, Inc. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Command-line application that demonstrates using BigQuery with credentials +obtained from an installed app. + +This sample is used on this page: + + https://cloud.google.com/bigquery/authentication + +For more information, see the README.md under /bigquery. +""" +# [START all] + +import argparse +import pprint + +from googleapiclient import discovery +from googleapiclient.errors import HttpError +from oauth2client import tools +from oauth2client.client import AccessTokenRefreshError +from oauth2client.client import flow_from_clientsecrets +from oauth2client.file import Storage + +SCOPES = ['https://www.googleapis.com/auth/bigquery'] +# Update with the full path to your client secrets json file. +CLIENT_SECRETS = 'client_secrets.json' + + +def main(args): + storage = Storage('credentials.dat') + credentials = storage.get() + + if credentials is None or credentials.invalid: + flow = flow_from_clientsecrets( + CLIENT_SECRETS, scope=SCOPES) + # run_flow will prompt the user to authorize the application's + # access to BigQuery and return the credentials. + credentials = tools.run_flow(flow, storage, args) + + # Create a BigQuery client using the credentials. + bigquery_service = discovery.build( + 'bigquery', 'v2', credentials=credentials) + + # List all datasets in BigQuery + try: + datasets = bigquery_service.datasets() + listReply = datasets.list(projectId=args.project_id).execute() + print('Dataset list:') + pprint.pprint(listReply) + + except HttpError as err: + print('Error in listDatasets:') + pprint.pprint(err.content) + + except AccessTokenRefreshError: + print('Credentials have been revoked or expired, please re-run' + 'the application to re-authorize') + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter, + # Use oauth2client's argparse as a base, so that the flags needed + # for run_flow are available. + parents=[tools.argparser]) + parser.add_argument( + 'project_id', help='Your Google Cloud Project ID.') + args = parser.parse_args() + main(args) +# [END all] diff --git a/bigquery/api/installed_app_test.py b/bigquery/api/installed_app_test.py new file mode 100644 index 000000000000..e8265f4a4007 --- /dev/null +++ b/bigquery/api/installed_app_test.py @@ -0,0 +1,45 @@ +# Copyright 2015, Google, Inc. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import re + +import installed_app +from oauth2client.client import GoogleCredentials + + +class Namespace(object): + def __init__(self, **kwargs): + self.__dict__.update(kwargs) + + +def test_main(cloud_config, monkeypatch, capsys): + installed_app.CLIENT_SECRETS = cloud_config.client_secrets + + # Replace the user credentials flow with Application Default Credentials. + # Unfortunately, there's no easy way to fully test the user flow. + def mock_run_flow(flow, storage, args): + return GoogleCredentials.get_application_default() + + monkeypatch.setattr(installed_app.tools, 'run_flow', mock_run_flow) + + args = Namespace( + project_id=cloud_config.project, + logging_level='INFO', + noauth_local_webserver=True) + + installed_app.main(args) + + out, _ = capsys.readouterr() + + assert re.search(re.compile( + r'bigquery#datasetList', re.DOTALL), out)