Skip to content

Commit 9c4867a

Browse files
committed
Merge pull request #864 from dhermes/connection-factories
Adding Connection factories for credentials.
2 parents 29a52d6 + d953994 commit 9c4867a

File tree

5 files changed

+143
-9
lines changed

5 files changed

+143
-9
lines changed

gcloud/connection.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121

2222
import httplib2
2323

24+
from gcloud.credentials import get_credentials
25+
from gcloud.credentials import get_for_service_account_json
26+
from gcloud.credentials import get_for_service_account_p12
2427
from gcloud.exceptions import make_exception
2528

2629

@@ -112,6 +115,68 @@ def _create_scoped_credentials(credentials, scope):
112115
credentials = credentials.create_scoped(scope)
113116
return credentials
114117

118+
@classmethod
119+
def from_service_account_json(cls, json_credentials_path, *args, **kwargs):
120+
"""Factory to retrieve JSON credentials while creating connection.
121+
122+
:type json_credentials_path: string
123+
:param json_credentials_path: The path to a private key file (this file
124+
was given to you when you created the
125+
service account). This file must contain
126+
a JSON object with a private key and
127+
other credentials information (downloaded
128+
from the Google APIs console).
129+
130+
:rtype: :class:`gcloud.connection.Connection`
131+
:returns: The connection created with the retrieved JSON credentials.
132+
"""
133+
credentials = get_for_service_account_json(json_credentials_path)
134+
if 'credentials' in kwargs:
135+
raise TypeError('credentials must not be in keyword arguments')
136+
kwargs['credentials'] = credentials
137+
return cls(*args, **kwargs)
138+
139+
@classmethod
140+
def from_service_account_p12(cls, client_email, private_key_path,
141+
*args, **kwargs):
142+
"""Factory to retrieve P12 credentials while creating connection.
143+
144+
.. note::
145+
Unless you have an explicit reason to use a PKCS12 key for your
146+
service account, we recommend using a JSON key.
147+
148+
:type client_email: string
149+
:param client_email: The e-mail attached to the service account.
150+
151+
:type private_key_path: string
152+
:param private_key_path: The path to a private key file (this file was
153+
given to you when you created the service
154+
account). This file must be in P12 format.
155+
156+
:rtype: :class:`gcloud.connection.Connection`
157+
:returns: The connection created with the retrieved P12 credentials.
158+
"""
159+
credentials = get_for_service_account_p12(client_email,
160+
private_key_path)
161+
if 'credentials' in kwargs:
162+
raise TypeError('credentials must not be in keyword arguments')
163+
kwargs['credentials'] = credentials
164+
return cls(*args, **kwargs)
165+
166+
@classmethod
167+
def from_environment(cls, *args, **kwargs):
168+
"""Factory to retrieve implicit credentials while creating connection.
169+
170+
:rtype: :class:`gcloud.connection.Connection`
171+
:returns: The connection created with the retrieved implicit
172+
credentials.
173+
"""
174+
credentials = get_credentials()
175+
if 'credentials' in kwargs:
176+
raise TypeError('credentials must not be in keyword arguments')
177+
kwargs['credentials'] = credentials
178+
return cls(*args, **kwargs)
179+
115180

116181
class JSONConnection(Connection):
117182
"""A connection to a Google JSON-based API.

gcloud/datastore/_implicit_environ.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
from gcloud._helpers import _app_engine_id
2424
from gcloud._helpers import _compute_engine_id
2525
from gcloud._helpers import _lazy_property_deco
26-
from gcloud.credentials import get_credentials
2726
from gcloud.datastore.connection import Connection
2827

2928

@@ -122,8 +121,7 @@ def get_connection():
122121
:rtype: :class:`gcloud.datastore.connection.Connection`
123122
:returns: A connection defined with the proper credentials.
124123
"""
125-
credentials = get_credentials()
126-
return Connection(credentials=credentials)
124+
return Connection.from_environment()
127125

128126

129127
def set_default_connection(connection=None):

gcloud/pubsub/__init__.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626

2727
from gcloud._helpers import get_default_project
2828
from gcloud._helpers import set_default_project
29-
from gcloud.credentials import get_credentials
3029
from gcloud.pubsub import _implicit_environ
3130
from gcloud.pubsub._implicit_environ import get_default_connection
3231
from gcloud.pubsub.api import list_subscriptions
@@ -75,5 +74,4 @@ def get_connection():
7574
:rtype: :class:`gcloud.pubsub.connection.Connection`
7675
:returns: A connection defined with the proper credentials.
7776
"""
78-
credentials = get_credentials()
79-
return Connection(credentials=credentials)
77+
return Connection.from_environment()

gcloud/storage/_implicit_environ.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020

2121

2222
from gcloud._helpers import _lazy_property_deco
23-
from gcloud.credentials import get_credentials
2423
from gcloud.storage.connection import Connection
2524

2625

@@ -78,8 +77,7 @@ def get_connection():
7877
:rtype: :class:`gcloud.storage.connection.Connection`
7978
:returns: A connection defined with the proper credentials.
8079
"""
81-
credentials = get_credentials()
82-
return Connection(credentials=credentials)
80+
return Connection.from_environment()
8381

8482

8583
def set_default_connection(connection=None):

gcloud/test_connection.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,81 @@ def test_user_agent_format(self):
7171
conn = self._makeOne()
7272
self.assertEqual(conn.USER_AGENT, expected_ua)
7373

74+
def _from_service_account_json_helper(self, **kwargs):
75+
from gcloud._testing import _Monkey
76+
from gcloud import connection
77+
78+
KLASS = self._getTargetClass()
79+
CREDS = object()
80+
_CALLED = []
81+
82+
def mock_creds(arg1):
83+
_CALLED.append((arg1,))
84+
return CREDS
85+
86+
FOO = object()
87+
with _Monkey(connection, get_for_service_account_json=mock_creds):
88+
conn = KLASS.from_service_account_json(FOO, **kwargs)
89+
90+
self.assertTrue(conn.credentials is CREDS)
91+
self.assertEqual(_CALLED, [(FOO,)])
92+
93+
def test_from_service_account_json(self):
94+
self._from_service_account_json_helper()
95+
96+
def test_from_service_account_json_fail(self):
97+
with self.assertRaises(TypeError):
98+
self._from_service_account_json_helper(credentials=None)
99+
100+
def _from_service_account_p12_helper(self, **kwargs):
101+
from gcloud._testing import _Monkey
102+
from gcloud import connection
103+
104+
KLASS = self._getTargetClass()
105+
CREDS = object()
106+
_CALLED = []
107+
108+
def mock_creds(arg1, arg2):
109+
_CALLED.append((arg1, arg2))
110+
return CREDS
111+
112+
FOO = object()
113+
BAR = object()
114+
with _Monkey(connection, get_for_service_account_p12=mock_creds):
115+
conn = KLASS.from_service_account_p12(FOO, BAR, **kwargs)
116+
117+
self.assertTrue(conn.credentials is CREDS)
118+
self.assertEqual(_CALLED, [(FOO, BAR)])
119+
120+
def test_from_service_account_p12(self):
121+
self._from_service_account_p12_helper()
122+
123+
def test_from_service_account_p12_fail(self):
124+
with self.assertRaises(TypeError):
125+
self._from_service_account_p12_helper(credentials=None)
126+
127+
def _from_environment_helper(self, **kwargs):
128+
from gcloud._testing import _Monkey
129+
from gcloud import connection
130+
131+
KLASS = self._getTargetClass()
132+
CREDS = object()
133+
134+
def mock_creds():
135+
return CREDS
136+
137+
with _Monkey(connection, get_credentials=mock_creds):
138+
conn = KLASS.from_environment(**kwargs)
139+
140+
self.assertTrue(conn.credentials is CREDS)
141+
142+
def test_from_environment(self):
143+
self._from_environment_helper()
144+
145+
def test_from_environment_fail(self):
146+
with self.assertRaises(TypeError):
147+
self._from_environment_helper(credentials=None)
148+
74149

75150
class TestJSONConnection(unittest2.TestCase):
76151

0 commit comments

Comments
 (0)