From 6ebc65e9124b2cef401e41922c412b5c48454baf Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Fri, 20 Mar 2015 13:56:24 -0400 Subject: [PATCH 1/4] #741: hoist 'get_scoped_connection' into '_helpers'. Implement 'datastore._implicit_environ.get_connection' and 'storage.get_connection' in terms of it. --- gcloud/_helpers.py | 19 +++++++++++++++ gcloud/datastore/_implicit_environ.py | 6 ++--- gcloud/datastore/test__implicit_environ.py | 2 ++ gcloud/storage/__init__.py | 5 ++-- gcloud/storage/test___init__.py | 2 ++ gcloud/test__helpers.py | 28 ++++++++++++++++++++++ 6 files changed, 55 insertions(+), 7 deletions(-) diff --git a/gcloud/_helpers.py b/gcloud/_helpers.py index ab730c947b2a..1ba836842b84 100644 --- a/gcloud/_helpers.py +++ b/gcloud/_helpers.py @@ -31,6 +31,8 @@ class Local(object): except ImportError: app_identity = None +from gcloud import credentials + class _LocalStack(Local): """Manage a thread-local LIFO stack of resources. @@ -236,3 +238,20 @@ def __init__(self, project=None, implicit=False): _DEFAULTS = _DefaultsContainer(implicit=True) + + +def get_scoped_connection(klass, scopes): + """Create a scoped connection to GCloud. + + :type klass: type + :param klass: the specific ``Connection`` class to instantiate. + + :type scopes: list of URLs + :param scopes: the effective service auth scopes for the connection. + + :rtype: instance of ``klass`` + :returns: A connection defined with the proper credentials. + """ + implicit_credentials = credentials.get_credentials() + scoped_credentials = implicit_credentials.create_scoped(scopes) + return klass(credentials=scoped_credentials) diff --git a/gcloud/datastore/_implicit_environ.py b/gcloud/datastore/_implicit_environ.py index f48619e2dc81..024b304aa789 100644 --- a/gcloud/datastore/_implicit_environ.py +++ b/gcloud/datastore/_implicit_environ.py @@ -23,7 +23,7 @@ from gcloud._helpers import _app_engine_id from gcloud._helpers import _compute_engine_id from gcloud._helpers import _lazy_property_deco -from gcloud import credentials +from gcloud._helpers import get_scoped_connection from gcloud.datastore.connection import Connection @@ -126,9 +126,7 @@ def get_connection(): :rtype: :class:`gcloud.datastore.connection.Connection` :returns: A connection defined with the proper credentials. """ - implicit_credentials = credentials.get_credentials() - scoped_credentials = implicit_credentials.create_scoped(SCOPE) - return Connection(credentials=scoped_credentials) + return get_scoped_connection(Connection, SCOPE) def set_default_connection(connection=None): diff --git a/gcloud/datastore/test__implicit_environ.py b/gcloud/datastore/test__implicit_environ.py index 4c41d8eb9d0c..9f2d7018041e 100644 --- a/gcloud/datastore/test__implicit_environ.py +++ b/gcloud/datastore/test__implicit_environ.py @@ -305,6 +305,7 @@ def _callFUT(self): def test_it(self): from gcloud import credentials + from gcloud.datastore._implicit_environ import SCOPE from gcloud.datastore.connection import Connection from gcloud.test_credentials import _Client from gcloud._testing import _Monkey @@ -314,6 +315,7 @@ def test_it(self): found = self._callFUT() self.assertTrue(isinstance(found, Connection)) self.assertTrue(found._credentials is client._signed) + self.assertEqual(found._credentials._scopes, SCOPE) self.assertTrue(client._get_app_default_called) diff --git a/gcloud/storage/__init__.py b/gcloud/storage/__init__.py index 1040466863e2..10e7411c25d5 100644 --- a/gcloud/storage/__init__.py +++ b/gcloud/storage/__init__.py @@ -41,6 +41,7 @@ import os from gcloud import credentials +from gcloud._helpers import get_scoped_connection from gcloud._helpers import get_default_project from gcloud._helpers import set_default_project from gcloud.storage import _implicit_environ @@ -133,6 +134,4 @@ def get_connection(): :rtype: :class:`gcloud.storage.connection.Connection` :returns: A connection defined with the proper credentials. """ - implicit_credentials = credentials.get_credentials() - scoped_credentials = implicit_credentials.create_scoped(SCOPE) - return Connection(credentials=scoped_credentials) + return get_scoped_connection(Connection, SCOPE) diff --git a/gcloud/storage/test___init__.py b/gcloud/storage/test___init__.py index d4a1e3dfca8e..86127b6b5117 100644 --- a/gcloud/storage/test___init__.py +++ b/gcloud/storage/test___init__.py @@ -23,6 +23,7 @@ def _callFUT(self, *args, **kw): def test_it(self): from gcloud import credentials + from gcloud.storage import SCOPE from gcloud.storage.connection import Connection from gcloud.test_credentials import _Client from gcloud._testing import _Monkey @@ -31,6 +32,7 @@ def test_it(self): found = self._callFUT() self.assertTrue(isinstance(found, Connection)) self.assertTrue(found._credentials is client._signed) + self.assertEqual(found._credentials._scopes, SCOPE) self.assertTrue(client._get_app_default_called) diff --git a/gcloud/test__helpers.py b/gcloud/test__helpers.py index a543e3245f73..fce9476cf692 100644 --- a/gcloud/test__helpers.py +++ b/gcloud/test__helpers.py @@ -302,6 +302,34 @@ def test_descriptor_for_project(self): self.assertTrue('project' in _helpers._DEFAULTS.__dict__) +class Test_get_scoped_connection(unittest2.TestCase): + + def _callFUT(self, klass, scopes): + from gcloud._helpers import get_scoped_connection + return get_scoped_connection(klass, scopes) + + def test_it(self): + from gcloud import credentials + from gcloud.test_credentials import _Client + from gcloud._testing import _Monkey + + class _Connection(object): + def __init__(self, credentials): + self._credentials = credentials + + SCOPES = ('https://www.googleapis.com/auth/example', + 'https://www.googleapis.com/auth/userinfo.email') + + client = _Client() + with _Monkey(credentials, client=client): + found = self._callFUT(_Connection, SCOPES) + + self.assertTrue(isinstance(found, _Connection)) + self.assertTrue(found._credentials is client._signed) + self.assertEqual(found._credentials._scopes, SCOPES) + self.assertTrue(client._get_app_default_called) + + class _AppIdentity(object): def __init__(self, app_id): From 55889871823e6cf9b2add4dd5f6d63e22af5e111 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Fri, 20 Mar 2015 16:58:29 -0400 Subject: [PATCH 2/4] Move '_helpers.get_scoped_connection' -> 'connection. --- gcloud/_helpers.py | 19 ------------------ gcloud/connection.py | 18 +++++++++++++++++ gcloud/datastore/_implicit_environ.py | 2 +- gcloud/storage/__init__.py | 2 +- gcloud/test__helpers.py | 28 --------------------------- gcloud/test_connection.py | 28 +++++++++++++++++++++++++++ 6 files changed, 48 insertions(+), 49 deletions(-) diff --git a/gcloud/_helpers.py b/gcloud/_helpers.py index 1ba836842b84..ab730c947b2a 100644 --- a/gcloud/_helpers.py +++ b/gcloud/_helpers.py @@ -31,8 +31,6 @@ class Local(object): except ImportError: app_identity = None -from gcloud import credentials - class _LocalStack(Local): """Manage a thread-local LIFO stack of resources. @@ -238,20 +236,3 @@ def __init__(self, project=None, implicit=False): _DEFAULTS = _DefaultsContainer(implicit=True) - - -def get_scoped_connection(klass, scopes): - """Create a scoped connection to GCloud. - - :type klass: type - :param klass: the specific ``Connection`` class to instantiate. - - :type scopes: list of URLs - :param scopes: the effective service auth scopes for the connection. - - :rtype: instance of ``klass`` - :returns: A connection defined with the proper credentials. - """ - implicit_credentials = credentials.get_credentials() - scoped_credentials = implicit_credentials.create_scoped(scopes) - return klass(credentials=scoped_credentials) diff --git a/gcloud/connection.py b/gcloud/connection.py index c56a27ff8b8f..0b8fba2a9034 100644 --- a/gcloud/connection.py +++ b/gcloud/connection.py @@ -20,6 +20,7 @@ import httplib2 +from gcloud.credentials import get_credentials from gcloud.exceptions import make_exception @@ -297,3 +298,20 @@ def api_request(self, method, path, query_params=None, return json.loads(content) return content + + +def get_scoped_connection(klass, scopes): + """Create a scoped connection to GCloud. + + :type klass: type + :param klass: the specific ``Connection`` class to instantiate. + + :type scopes: list of URLs + :param scopes: the effective service auth scopes for the connection. + + :rtype: instance of ``klass`` + :returns: A connection defined with the proper credentials. + """ + implicit_credentials = get_credentials() + scoped_credentials = implicit_credentials.create_scoped(scopes) + return klass(credentials=scoped_credentials) diff --git a/gcloud/datastore/_implicit_environ.py b/gcloud/datastore/_implicit_environ.py index 024b304aa789..0d18b7540bf0 100644 --- a/gcloud/datastore/_implicit_environ.py +++ b/gcloud/datastore/_implicit_environ.py @@ -23,7 +23,7 @@ from gcloud._helpers import _app_engine_id from gcloud._helpers import _compute_engine_id from gcloud._helpers import _lazy_property_deco -from gcloud._helpers import get_scoped_connection +from gcloud.connection import get_scoped_connection from gcloud.datastore.connection import Connection diff --git a/gcloud/storage/__init__.py b/gcloud/storage/__init__.py index 10e7411c25d5..200d863ea544 100644 --- a/gcloud/storage/__init__.py +++ b/gcloud/storage/__init__.py @@ -41,9 +41,9 @@ import os from gcloud import credentials -from gcloud._helpers import get_scoped_connection from gcloud._helpers import get_default_project from gcloud._helpers import set_default_project +from gcloud.connection import get_scoped_connection from gcloud.storage import _implicit_environ from gcloud.storage._implicit_environ import get_default_bucket from gcloud.storage._implicit_environ import get_default_connection diff --git a/gcloud/test__helpers.py b/gcloud/test__helpers.py index fce9476cf692..a543e3245f73 100644 --- a/gcloud/test__helpers.py +++ b/gcloud/test__helpers.py @@ -302,34 +302,6 @@ def test_descriptor_for_project(self): self.assertTrue('project' in _helpers._DEFAULTS.__dict__) -class Test_get_scoped_connection(unittest2.TestCase): - - def _callFUT(self, klass, scopes): - from gcloud._helpers import get_scoped_connection - return get_scoped_connection(klass, scopes) - - def test_it(self): - from gcloud import credentials - from gcloud.test_credentials import _Client - from gcloud._testing import _Monkey - - class _Connection(object): - def __init__(self, credentials): - self._credentials = credentials - - SCOPES = ('https://www.googleapis.com/auth/example', - 'https://www.googleapis.com/auth/userinfo.email') - - client = _Client() - with _Monkey(credentials, client=client): - found = self._callFUT(_Connection, SCOPES) - - self.assertTrue(isinstance(found, _Connection)) - self.assertTrue(found._credentials is client._signed) - self.assertEqual(found._credentials._scopes, SCOPES) - self.assertTrue(client._get_app_default_called) - - class _AppIdentity(object): def __init__(self, app_id): diff --git a/gcloud/test_connection.py b/gcloud/test_connection.py index 2cdda517eca8..8b6261ba3725 100644 --- a/gcloud/test_connection.py +++ b/gcloud/test_connection.py @@ -347,3 +347,31 @@ def __init__(self, headers, content): def request(self, **kw): self._called_with = kw return self._response, self._content + + +class Test_get_scoped_connection(unittest2.TestCase): + + def _callFUT(self, klass, scopes): + from gcloud.connection import get_scoped_connection + return get_scoped_connection(klass, scopes) + + def test_it(self): + from gcloud import credentials + from gcloud.test_credentials import _Client + from gcloud._testing import _Monkey + + class _Connection(object): + def __init__(self, credentials): + self._credentials = credentials + + SCOPES = ('https://www.googleapis.com/auth/example', + 'https://www.googleapis.com/auth/userinfo.email') + + client = _Client() + with _Monkey(credentials, client=client): + found = self._callFUT(_Connection, SCOPES) + + self.assertTrue(isinstance(found, _Connection)) + self.assertTrue(found._credentials is client._signed) + self.assertEqual(found._credentials._scopes, SCOPES) + self.assertTrue(client._get_app_default_called) From 3e8e4bcaecd3d7ace15db2eb152cb36066ab4f83 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Fri, 20 Mar 2015 17:02:10 -0400 Subject: [PATCH 3/4] Improve description of 'klass' type. [ci skip] --- gcloud/connection.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcloud/connection.py b/gcloud/connection.py index 0b8fba2a9034..5ede41322086 100644 --- a/gcloud/connection.py +++ b/gcloud/connection.py @@ -303,7 +303,7 @@ def api_request(self, method, path, query_params=None, def get_scoped_connection(klass, scopes): """Create a scoped connection to GCloud. - :type klass: type + :type klass: subclass of :class:`gcloud.connection.Connection` :param klass: the specific ``Connection`` class to instantiate. :type scopes: list of URLs From 83d4e89698e6c02f9a114ebfc3675a7cd3bdac1d Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Mon, 23 Mar 2015 15:37:32 -0400 Subject: [PATCH 4/4] Relax absolute pin on protobuf. We should allow versions later than the one we know is 'least acceptable'. --- tox.ini | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tox.ini b/tox.ini index 5d767ed9b5b9..b4c53ad25234 100644 --- a/tox.ini +++ b/tox.ini @@ -10,7 +10,7 @@ commands = deps = nose unittest2 - protobuf==3.0.0-alpha-1 + protobuf>=3.0.0-alpha-1 [testenv:cover] basepython = @@ -20,7 +20,7 @@ commands = deps = nose unittest2 - protobuf==3.0.0-alpha-1 + protobuf>=3.0.0-alpha-1 coverage nosexcover @@ -56,7 +56,7 @@ deps = pep8 pylint unittest2 - protobuf==3.0.0-alpha-1 + protobuf>=3.0.0-alpha-1 [testenv:regression] basepython = @@ -65,7 +65,7 @@ commands = {toxinidir}/scripts/run_regression.sh deps = unittest2 - protobuf==3.0.0-alpha-1 + protobuf>=3.0.0-alpha-1 [testenv:regression3] basepython = @@ -77,4 +77,4 @@ deps = # Use a development checkout of oauth2client until a release is made # which fixes https://github.com/google/oauth2client/issues/125 -egit+https://github.com/google/oauth2client.git#egg=oauth2client - protobuf==3.0.0-alpha-1 + protobuf>=3.0.0-alpha-1