Skip to content

Commit f554571

Browse files
committed
Only requiring HTTP object to make datastore RPC-over-HTTP.
1 parent a7fcd2f commit f554571

2 files changed

Lines changed: 52 additions & 51 deletions

File tree

datastore/google/cloud/datastore/_http.py

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,11 @@
4848
_CLIENT_INFO = connection_module.CLIENT_INFO_TEMPLATE.format(__version__)
4949

5050

51-
def _request(connection, project, method, data):
51+
def _request(http, project, method, data, base_url):
5252
"""Make a request over the Http transport to the Cloud Datastore API.
5353
54-
:type connection: :class:`Connection`
55-
:param connection: A connection object that contains helpful
56-
information for making requests.
54+
:type http: :class:`~httplib2.Http`
55+
:param http: HTTP object to make requests.
5756
5857
:type project: str
5958
:param project: The project to make the request for.
@@ -66,6 +65,9 @@ def _request(connection, project, method, data):
6665
:param data: The data to send with the API call.
6766
Typically this is a serialized Protobuf string.
6867
68+
:type base_url: str
69+
:param base_url: The base URL where the API lives.
70+
6971
:rtype: str
7072
:returns: The string response content from the API call.
7173
:raises: :class:`google.cloud.exceptions.GoogleCloudError` if the
@@ -77,8 +79,8 @@ def _request(connection, project, method, data):
7779
'User-Agent': connection_module.DEFAULT_USER_AGENT,
7880
connection_module.CLIENT_INFO_HEADER: _CLIENT_INFO,
7981
}
80-
api_url = build_api_url(project, method, connection.api_base_url)
81-
headers, content = connection.http.request(
82+
api_url = build_api_url(project, method, base_url)
83+
headers, content = http.request(
8284
uri=api_url, method='POST', headers=headers, body=data)
8385

8486
status = headers['status']
@@ -90,12 +92,11 @@ def _request(connection, project, method, data):
9092
return content
9193

9294

93-
def _rpc(connection, project, method, request_pb, response_pb_cls):
95+
def _rpc(http, project, method, base_url, request_pb, response_pb_cls):
9496
"""Make a protobuf RPC request.
9597
96-
:type connection: :class:`Connection`
97-
:param connection: A connection object that contains helpful
98-
information for making requests.
98+
:type http: :class:`~httplib2.Http`
99+
:param http: HTTP object to make requests.
99100
100101
:type project: str
101102
:param project: The project to connect to. This is
@@ -104,6 +105,9 @@ def _rpc(connection, project, method, request_pb, response_pb_cls):
104105
:type method: str
105106
:param method: The name of the method to invoke.
106107
108+
:type base_url: str
109+
:param base_url: The base URL where the API lives.
110+
107111
:type request_pb: :class:`google.protobuf.message.Message` instance
108112
:param request_pb: the protobuf instance representing the request.
109113
@@ -115,8 +119,9 @@ def _rpc(connection, project, method, request_pb, response_pb_cls):
115119
:rtype: :class:`google.protobuf.message.Message`
116120
:returns: The RPC message parsed from the response.
117121
"""
118-
response = _request(connection=connection, project=project,
119-
method=method, data=request_pb.SerializeToString())
122+
req_data = request_pb.SerializeToString()
123+
response = _request(
124+
http, project, method, req_data, base_url)
120125
return response_pb_cls.FromString(response)
121126

122127

@@ -135,7 +140,6 @@ def build_api_url(project, method, base_url):
135140
136141
:type base_url: str
137142
:param base_url: The base URL where the API lives.
138-
You shouldn't have to provide this.
139143
140144
:rtype: str
141145
:returns: The API URL created.
@@ -174,8 +178,9 @@ def lookup(self, project, request_pb):
174178
:rtype: :class:`.datastore_pb2.LookupResponse`
175179
:returns: The returned protobuf response object.
176180
"""
177-
return _rpc(self.connection, project, 'lookup', request_pb,
178-
_datastore_pb2.LookupResponse)
181+
return _rpc(self.connection.http, project, 'lookup',
182+
self.connection.api_base_url,
183+
request_pb, _datastore_pb2.LookupResponse)
179184

180185
def run_query(self, project, request_pb):
181186
"""Perform a ``runQuery`` request.
@@ -190,8 +195,9 @@ def run_query(self, project, request_pb):
190195
:rtype: :class:`.datastore_pb2.RunQueryResponse`
191196
:returns: The returned protobuf response object.
192197
"""
193-
return _rpc(self.connection, project, 'runQuery', request_pb,
194-
_datastore_pb2.RunQueryResponse)
198+
return _rpc(self.connection.http, project, 'runQuery',
199+
self.connection.api_base_url,
200+
request_pb, _datastore_pb2.RunQueryResponse)
195201

196202
def begin_transaction(self, project, request_pb):
197203
"""Perform a ``beginTransaction`` request.
@@ -207,8 +213,9 @@ def begin_transaction(self, project, request_pb):
207213
:rtype: :class:`.datastore_pb2.BeginTransactionResponse`
208214
:returns: The returned protobuf response object.
209215
"""
210-
return _rpc(self.connection, project, 'beginTransaction', request_pb,
211-
_datastore_pb2.BeginTransactionResponse)
216+
return _rpc(self.connection.http, project, 'beginTransaction',
217+
self.connection.api_base_url,
218+
request_pb, _datastore_pb2.BeginTransactionResponse)
212219

213220
def commit(self, project, request_pb):
214221
"""Perform a ``commit`` request.
@@ -223,8 +230,9 @@ def commit(self, project, request_pb):
223230
:rtype: :class:`.datastore_pb2.CommitResponse`
224231
:returns: The returned protobuf response object.
225232
"""
226-
return _rpc(self.connection, project, 'commit', request_pb,
227-
_datastore_pb2.CommitResponse)
233+
return _rpc(self.connection.http, project, 'commit',
234+
self.connection.api_base_url,
235+
request_pb, _datastore_pb2.CommitResponse)
228236

229237
def rollback(self, project, request_pb):
230238
"""Perform a ``rollback`` request.
@@ -239,8 +247,9 @@ def rollback(self, project, request_pb):
239247
:rtype: :class:`.datastore_pb2.RollbackResponse`
240248
:returns: The returned protobuf response object.
241249
"""
242-
return _rpc(self.connection, project, 'rollback', request_pb,
243-
_datastore_pb2.RollbackResponse)
250+
return _rpc(self.connection.http, project, 'rollback',
251+
self.connection.api_base_url,
252+
request_pb, _datastore_pb2.RollbackResponse)
244253

245254
def allocate_ids(self, project, request_pb):
246255
"""Perform an ``allocateIds`` request.
@@ -255,8 +264,9 @@ def allocate_ids(self, project, request_pb):
255264
:rtype: :class:`.datastore_pb2.AllocateIdsResponse`
256265
:returns: The returned protobuf response object.
257266
"""
258-
return _rpc(self.connection, project, 'allocateIds', request_pb,
259-
_datastore_pb2.AllocateIdsResponse)
267+
return _rpc(self.connection.http, project, 'allocateIds',
268+
self.connection.api_base_url,
269+
request_pb, _datastore_pb2.AllocateIdsResponse)
260270

261271

262272
class Connection(connection_module.Connection):

datastore/unit_tests/test__http.py

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,12 @@ def test_success(self):
3434
data = b'DATA'
3535
uri = 'http://api-url'
3636

37-
# Make mock Connection object with canned response.
38-
conn = _Connection(uri)
37+
# Make mock HTTP object with canned response.
3938
response_data = 'CONTENT'
40-
http = conn.http = Http({'status': '200'}, response_data)
39+
http = Http({'status': '200'}, response_data)
4140

4241
# Call actual function under test.
43-
response = self._call_fut(conn, project, method, data)
42+
response = self._call_fut(http, project, method, data, uri)
4443
self.assertEqual(response, response_data)
4544

4645
# Check that the mocks were called as expected.
@@ -67,17 +66,15 @@ def test_failure(self):
6766
data = 'DATA'
6867
uri = 'http://api-url'
6968

70-
# Make mock Connection object with canned response.
71-
conn = _Connection(uri)
72-
conn.api_base_url = uri
69+
# Make mock HTTP object with canned response.
7370
error = status_pb2.Status()
7471
error.message = 'Entity value is indexed.'
7572
error.code = code_pb2.FAILED_PRECONDITION
76-
conn.http = Http({'status': '400'}, error.SerializeToString())
73+
http = Http({'status': '400'}, error.SerializeToString())
7774

7875
# Call actual function under test.
7976
with self.assertRaises(BadRequest) as exc:
80-
self._call_fut(conn, project, method, data)
77+
self._call_fut(http, project, method, data, uri)
8178

8279
# Check that the mocks were called as expected.
8380
expected_message = '400 Entity value is indexed.'
@@ -95,9 +92,10 @@ def _call_fut(*args, **kwargs):
9592
def test_it(self):
9693
from google.cloud.proto.datastore.v1 import datastore_pb2
9794

98-
connection = object()
95+
http = object()
9996
project = 'projectOK'
10097
method = 'beginTransaction'
98+
base_url = 'test.invalid'
10199
request_pb = datastore_pb2.BeginTransactionRequest(
102100
project_id=project)
103101

@@ -107,13 +105,13 @@ def test_it(self):
107105
return_value=response_pb.SerializeToString())
108106
with patch as mock_request:
109107
result = self._call_fut(
110-
connection, project, method, request_pb,
111-
datastore_pb2.BeginTransactionResponse)
108+
http, project, method, base_url,
109+
request_pb, datastore_pb2.BeginTransactionResponse)
112110
self.assertEqual(result, response_pb)
113111

114112
mock_request.assert_called_once_with(
115-
connection=connection, data=request_pb.SerializeToString(),
116-
method=method, project=project)
113+
http, project, method, request_pb.SerializeToString(),
114+
base_url)
117115

118116

119117
class Test_DatastoreAPIOverHttp(unittest.TestCase):
@@ -135,7 +133,8 @@ def test_constructor(self):
135133
def test_lookup(self):
136134
from google.cloud.proto.datastore.v1 import datastore_pb2
137135

138-
connection = object()
136+
connection = mock.Mock(
137+
api_base_url='test.invalid', spec=['http', 'api_base_url'])
139138
ds_api = self._make_one(connection)
140139

141140
project = 'project'
@@ -149,8 +148,9 @@ def test_lookup(self):
149148
self.assertIs(result, mock.sentinel.looked_up)
150149

151150
mock_rpc.assert_called_once_with(
152-
connection, project, 'lookup', request_pb,
153-
datastore_pb2.LookupResponse)
151+
connection.http, project, 'lookup',
152+
connection.api_base_url,
153+
request_pb, datastore_pb2.LookupResponse)
154154

155155

156156
class TestConnection(unittest.TestCase):
@@ -875,12 +875,3 @@ def __init__(self, headers, content):
875875
def request(self, **kw):
876876
self._called_with = kw
877877
return self._response, self._content
878-
879-
880-
class _Connection(object):
881-
882-
host = None
883-
http = None
884-
885-
def __init__(self, api_base_url):
886-
self.api_base_url = api_base_url

0 commit comments

Comments
 (0)