diff --git a/README.rst b/README.rst index 766532b1adba..c952a9c4a359 100644 --- a/README.rst +++ b/README.rst @@ -99,7 +99,6 @@ to Cloud Storage using this Client Library. .. code:: python from gcloud import storage - storage.set_defaults() bucket = storage.get_bucket('bucket-id-here') # Then do other things... blob = bucket.get_blob('/remote/path/to/file.txt') diff --git a/docs/index.rst b/docs/index.rst index 1c9dbd83ee58..ca6ff2a94192 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -51,7 +51,6 @@ Cloud Storage .. code-block:: python from gcloud import storage - storage.set_defaults() bucket = storage.get_bucket('') blob = storage.Blob('my-test-file.txt', bucket=bucket) blob = blob.upload_contents_from_string('this is test content!') diff --git a/gcloud/pubsub/test__implicit_environ.py b/gcloud/pubsub/test__implicit_environ.py index 9061c2bb6c89..6f1f0a85f85f 100644 --- a/gcloud/pubsub/test__implicit_environ.py +++ b/gcloud/pubsub/test__implicit_environ.py @@ -18,7 +18,7 @@ class Test_get_default_connection(unittest2.TestCase): def _callFUT(self): - from gcloud.storage._implicit_environ import get_default_connection + from gcloud.pubsub._implicit_environ import get_default_connection return get_default_connection() def test_wo_override(self): diff --git a/gcloud/storage/__init__.py b/gcloud/storage/__init__.py index 5f76864320c6..3679fcc45709 100644 --- a/gcloud/storage/__init__.py +++ b/gcloud/storage/__init__.py @@ -17,7 +17,6 @@ You'll typically use these to get started with the API: >>> from gcloud import storage ->>> storage.set_defaults() >>> bucket = storage.get_bucket('bucket-id-here') >>> # Then do other things... >>> blob = bucket.get_blob('/remote/path/to/file.txt') @@ -43,10 +42,12 @@ from gcloud import credentials 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 SCOPE +from gcloud.storage._implicit_environ import get_connection from gcloud.storage._implicit_environ import get_default_bucket from gcloud.storage._implicit_environ import get_default_connection +from gcloud.storage._implicit_environ import set_default_connection from gcloud.storage.api import create_bucket from gcloud.storage.api import get_bucket from gcloud.storage.api import list_buckets @@ -57,10 +58,6 @@ from gcloud.storage.connection import Connection -SCOPE = ('https://www.googleapis.com/auth/devstorage.full_control', - 'https://www.googleapis.com/auth/devstorage.read_only', - 'https://www.googleapis.com/auth/devstorage.read_write') - _BUCKET_ENV_VAR_NAME = 'GCLOUD_BUCKET_NAME' @@ -90,16 +87,6 @@ def set_default_bucket(bucket=None): _implicit_environ._DEFAULTS.bucket = bucket -def set_default_connection(connection=None): - """Set default connection either explicitly or implicitly as fall-back. - - :type connection: :class:`gcloud.storage.connection.Connection` - :param connection: A connection provided to be the default. - """ - connection = connection or get_connection() - _implicit_environ._DEFAULTS.connection = connection - - def set_defaults(bucket=None, project=None, connection=None): """Set defaults either explicitly or implicitly as fall-back. @@ -119,20 +106,3 @@ def set_defaults(bucket=None, project=None, connection=None): # NOTE: `set_default_bucket` is called after `set_default_connection` # since `set_default_bucket` falls back to implicit connection. set_default_bucket(bucket=bucket) - - -def get_connection(): - """Shortcut method to establish a connection to Cloud Storage. - - Use this if you are going to access several buckets with the same - set of credentials: - - >>> from gcloud import storage - >>> connection = storage.get_connection() - >>> bucket1 = storage.get_bucket('bucket1', connection=connection) - >>> bucket2 = storage.get_bucket('bucket2', connection=connection) - - :rtype: :class:`gcloud.storage.connection.Connection` - :returns: A connection defined with the proper credentials. - """ - return get_scoped_connection(Connection, SCOPE) diff --git a/gcloud/storage/_implicit_environ.py b/gcloud/storage/_implicit_environ.py index 6e4c5b57a7b2..74899ff9fb9a 100644 --- a/gcloud/storage/_implicit_environ.py +++ b/gcloud/storage/_implicit_environ.py @@ -19,6 +19,16 @@ """ +from gcloud._helpers import _lazy_property_deco +from gcloud.connection import get_scoped_connection +from gcloud.storage.connection import Connection + + +SCOPE = ('https://www.googleapis.com/auth/devstorage.full_control', + 'https://www.googleapis.com/auth/devstorage.read_only', + 'https://www.googleapis.com/auth/devstorage.read_write') + + class _DefaultsContainer(object): """Container for defaults. @@ -29,9 +39,16 @@ class _DefaultsContainer(object): :param connection: Persistent implied connection from environment. """ - def __init__(self, bucket=None, connection=None): + @_lazy_property_deco + @staticmethod + def connection(): + """Return the implicit default connection..""" + return get_connection() + + def __init__(self, bucket=None, connection=None, implicit=False): self.bucket = bucket - self.connection = connection + if connection is not None or not implicit: + self.connection = connection def get_default_bucket(): @@ -52,4 +69,31 @@ def get_default_connection(): return _DEFAULTS.connection -_DEFAULTS = _DefaultsContainer() +def get_connection(): + """Shortcut method to establish a connection to Cloud Storage. + + Use this if you are going to access several buckets with the same + set of credentials: + + >>> from gcloud import storage + >>> connection = storage.get_connection() + >>> bucket1 = storage.get_bucket('bucket1', connection=connection) + >>> bucket2 = storage.get_bucket('bucket2', connection=connection) + + :rtype: :class:`gcloud.storage.connection.Connection` + :returns: A connection defined with the proper credentials. + """ + return get_scoped_connection(Connection, SCOPE) + + +def set_default_connection(connection=None): + """Set default connection either explicitly or implicitly as fall-back. + + :type connection: :class:`gcloud.storage.connection.Connection` + :param connection: A connection provided to be the default. + """ + connection = connection or get_connection() + _DEFAULTS.connection = connection + + +_DEFAULTS = _DefaultsContainer(implicit=True) diff --git a/gcloud/storage/api.py b/gcloud/storage/api.py index 2ac270102870..47956add611e 100644 --- a/gcloud/storage/api.py +++ b/gcloud/storage/api.py @@ -33,7 +33,6 @@ def lookup_bucket(bucket_name, connection=None): than catching an exception:: >>> from gcloud import storage - >>> storage.set_defaults() >>> bucket = storage.lookup_bucket('doesnt-exist') >>> print bucket None @@ -172,7 +171,6 @@ def create_bucket(bucket_name, project=None, connection=None): For example:: >>> from gcloud import storage - >>> storage.set_defaults() >>> bucket = storage.create_bucket('my-bucket') >>> print bucket diff --git a/gcloud/storage/test___init__.py b/gcloud/storage/test___init__.py index 86127b6b5117..46263469a110 100644 --- a/gcloud/storage/test___init__.py +++ b/gcloud/storage/test___init__.py @@ -15,27 +15,6 @@ import unittest2 -class Test_get_connection(unittest2.TestCase): - - def _callFUT(self, *args, **kw): - from gcloud.storage import get_connection - return get_connection(*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 - client = _Client() - with _Monkey(credentials, client=client): - 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) - - class Test_set_default_bucket(unittest2.TestCase): def setUp(self): @@ -137,52 +116,6 @@ def test_set_explicit_None_w_env_var_set(self): self.assertEqual(default_bucket.connection, CONNECTION) -class Test_set_default_connection(unittest2.TestCase): - - def setUp(self): - from gcloud.storage._testing import _setup_defaults - _setup_defaults(self) - - def tearDown(self): - from gcloud.storage._testing import _tear_down_defaults - _tear_down_defaults(self) - - def _callFUT(self, connection=None): - from gcloud.storage import set_default_connection - return set_default_connection(connection=connection) - - def test_set_explicit(self): - from gcloud.storage import _implicit_environ - - self.assertEqual(_implicit_environ.get_default_connection(), None) - fake_cnxn = object() - self._callFUT(connection=fake_cnxn) - self.assertEqual(_implicit_environ.get_default_connection(), fake_cnxn) - - def test_set_implicit(self): - from gcloud._testing import _Monkey - from gcloud import storage - from gcloud.storage import _implicit_environ - - self.assertEqual(_implicit_environ.get_default_connection(), None) - - fake_cnxn = object() - _called_args = [] - _called_kwargs = [] - - def mock_get_connection(*args, **kwargs): - _called_args.append(args) - _called_kwargs.append(kwargs) - return fake_cnxn - - with _Monkey(storage, get_connection=mock_get_connection): - self._callFUT() - - self.assertEqual(_implicit_environ.get_default_connection(), fake_cnxn) - self.assertEqual(_called_args, [()]) - self.assertEqual(_called_kwargs, [{}]) - - class Test_set_defaults(unittest2.TestCase): def _callFUT(self, bucket=None, project=None, connection=None): diff --git a/gcloud/storage/test__implicit_environ.py b/gcloud/storage/test__implicit_environ.py index 570a50f7d674..2176a7090066 100644 --- a/gcloud/storage/test__implicit_environ.py +++ b/gcloud/storage/test__implicit_environ.py @@ -27,9 +27,110 @@ def test_wo_override(self): class Test_get_default_connection(unittest2.TestCase): + def setUp(self): + from gcloud.storage._testing import _setup_defaults + _setup_defaults(self) + + def tearDown(self): + from gcloud.storage._testing import _tear_down_defaults + _tear_down_defaults(self) + def _callFUT(self): from gcloud.storage._implicit_environ import get_default_connection return get_default_connection() def test_wo_override(self): self.assertTrue(self._callFUT() is None) + + +class Test_get_connection(unittest2.TestCase): + + def _callFUT(self, *args, **kw): + from gcloud.storage._implicit_environ import get_connection + return get_connection(*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 + client = _Client() + with _Monkey(credentials, client=client): + 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) + + +class Test_set_default_connection(unittest2.TestCase): + + def setUp(self): + from gcloud.storage._testing import _setup_defaults + _setup_defaults(self) + + def tearDown(self): + from gcloud.storage._testing import _tear_down_defaults + _tear_down_defaults(self) + + def _callFUT(self, connection=None): + from gcloud.storage._implicit_environ import set_default_connection + return set_default_connection(connection=connection) + + def test_set_explicit(self): + from gcloud.storage import _implicit_environ + + self.assertEqual(_implicit_environ.get_default_connection(), None) + fake_cnxn = object() + self._callFUT(connection=fake_cnxn) + self.assertEqual(_implicit_environ.get_default_connection(), fake_cnxn) + + def test_set_implicit(self): + from gcloud._testing import _Monkey + from gcloud.storage import _implicit_environ + + self.assertEqual(_implicit_environ.get_default_connection(), None) + + fake_cnxn = object() + _called_args = [] + _called_kwargs = [] + + def mock_get_connection(*args, **kwargs): + _called_args.append(args) + _called_kwargs.append(kwargs) + return fake_cnxn + + with _Monkey(_implicit_environ, get_connection=mock_get_connection): + self._callFUT() + + self.assertEqual(_implicit_environ.get_default_connection(), fake_cnxn) + self.assertEqual(_called_args, [()]) + self.assertEqual(_called_kwargs, [{}]) + + +class Test_lazy_loading(unittest2.TestCase): + + def setUp(self): + from gcloud.storage._testing import _setup_defaults + _setup_defaults(self, implicit=True) + + def tearDown(self): + from gcloud.storage._testing import _tear_down_defaults + _tear_down_defaults(self) + + def test_descriptor_for_connection(self): + from gcloud._testing import _Monkey + from gcloud.storage import _implicit_environ + + self.assertFalse( + 'connection' in _implicit_environ._DEFAULTS.__dict__) + + DEFAULT = object() + + with _Monkey(_implicit_environ, get_connection=lambda: DEFAULT): + lazy_loaded = _implicit_environ._DEFAULTS.connection + + self.assertEqual(lazy_loaded, DEFAULT) + self.assertTrue( + 'connection' in _implicit_environ._DEFAULTS.__dict__) diff --git a/regression/storage.py b/regression/storage.py index 027d5b57cdc7..4a3cb1695f39 100644 --- a/regression/storage.py +++ b/regression/storage.py @@ -28,7 +28,6 @@ SHARED_BUCKETS = {} _helpers._PROJECT_ENV_VAR_NAME = 'GCLOUD_TESTS_PROJECT_ID' -storage.set_defaults() def setUpModule():