1818
1919from google .rpc import status_pb2
2020
21+ from gcloud ._helpers import make_stub
2122from gcloud import connection as connection_module
2223from gcloud .environment_vars import GCD_HOST
24+ from gcloud .exceptions import Conflict
2325from gcloud .exceptions import make_exception
2426from gcloud .datastore ._generated import datastore_pb2 as _datastore_pb2
27+ # pylint: disable=ungrouped-imports
28+ try :
29+ from grpc .beta .interfaces import StatusCode
30+ from grpc .framework .interfaces .face .face import AbortionError
31+ from gcloud .datastore ._generated import datastore_grpc_pb2
32+ DATASTORE_STUB_FACTORY = datastore_grpc_pb2 .beta_create_Datastore_stub
33+ except ImportError : # pragma: NO COVER
34+ _HAVE_GRPC = False
35+ DATASTORE_STUB_FACTORY = None
36+ StatusCode = None
37+ AbortionError = Exception
38+ else :
39+ _HAVE_GRPC = True
40+ # pylint: enable=ungrouped-imports
41+
42+
43+ DATASTORE_API_HOST = 'datastore.googleapis.com'
44+ """Datastore API request host."""
45+ DATASTORE_API_PORT = 443
46+ """Datastore API request port."""
47+ GRPC_TIMEOUT_SECONDS = 10
48+ """The default timeout to use for API requests via gRPC."""
2549
2650
2751class _DatastoreAPIOverHttp (object ):
2852 """Helper mapping datastore API methods.
2953
54+ Makes requests to send / receive protobuf content over HTTP/1.1.
55+
3056 Methods make bare API requests without any helpers for constructing
3157 the requests or parsing the responses.
3258
@@ -196,6 +222,139 @@ def allocate_ids(self, project, request_pb):
196222 _datastore_pb2 .AllocateIdsResponse )
197223
198224
225+ class _DatastoreAPIOverGRPC (object ):
226+ """Helper mapping datastore API methods.
227+
228+ Makes requests to send / receive protobuf content over gRPC.
229+
230+ Methods make bare API requests without any helpers for constructing
231+ the requests or parsing the responses.
232+
233+ :type connection: :class:`gcloud.datastore.connection.Connection`
234+ :param connection: A connection object that contains helpful
235+ information for making requests.
236+ """
237+
238+ def __init__ (self , connection ):
239+ self ._stub = make_stub (connection .credentials , connection .USER_AGENT ,
240+ DATASTORE_STUB_FACTORY , DATASTORE_API_HOST ,
241+ DATASTORE_API_PORT )
242+ self ._stub .__enter__ ()
243+
244+ def __del__ (self ):
245+ """Destructor for object.
246+
247+ Ensures that the stub is exited so the shell can close properly.
248+ """
249+ try :
250+ self ._stub .__exit__ (None , None , None )
251+ del self ._stub
252+ except AttributeError :
253+ pass
254+
255+ def lookup (self , project , request_pb ):
256+ """Perform a ``lookup`` request.
257+
258+ :type project: string
259+ :param project: The project to connect to. This is
260+ usually your project name in the cloud console.
261+
262+ :type request_pb: :class:`._generated.datastore_pb2.LookupRequest`
263+ :param request_pb: The request protobuf object.
264+
265+ :rtype: :class:`._generated.datastore_pb2.LookupResponse`
266+ :returns: The returned protobuf response object.
267+ """
268+ request_pb .project_id = project
269+ return self ._stub .Lookup (request_pb , GRPC_TIMEOUT_SECONDS )
270+
271+ def run_query (self , project , request_pb ):
272+ """Perform a ``runQuery`` request.
273+
274+ :type project: string
275+ :param project: The project to connect to. This is
276+ usually your project name in the cloud console.
277+
278+ :type request_pb: :class:`._generated.datastore_pb2.RunQueryRequest`
279+ :param request_pb: The request protobuf object.
280+
281+ :rtype: :class:`._generated.datastore_pb2.RunQueryResponse`
282+ :returns: The returned protobuf response object.
283+ """
284+ request_pb .project_id = project
285+ return self ._stub .RunQuery (request_pb , GRPC_TIMEOUT_SECONDS )
286+
287+ def begin_transaction (self , project , request_pb ):
288+ """Perform a ``beginTransaction`` request.
289+
290+ :type project: string
291+ :param project: The project to connect to. This is
292+ usually your project name in the cloud console.
293+
294+ :type request_pb:
295+ :class:`._generated.datastore_pb2.BeginTransactionRequest`
296+ :param request_pb: The request protobuf object.
297+
298+ :rtype: :class:`._generated.datastore_pb2.BeginTransactionResponse`
299+ :returns: The returned protobuf response object.
300+ """
301+ request_pb .project_id = project
302+ return self ._stub .BeginTransaction (request_pb , GRPC_TIMEOUT_SECONDS )
303+
304+ def commit (self , project , request_pb ):
305+ """Perform a ``commit`` request.
306+
307+ :type project: string
308+ :param project: The project to connect to. This is
309+ usually your project name in the cloud console.
310+
311+ :type request_pb: :class:`._generated.datastore_pb2.CommitRequest`
312+ :param request_pb: The request protobuf object.
313+
314+ :rtype: :class:`._generated.datastore_pb2.CommitResponse`
315+ :returns: The returned protobuf response object.
316+ """
317+ request_pb .project_id = project
318+ try :
319+ return self ._stub .Commit (request_pb , GRPC_TIMEOUT_SECONDS )
320+ except AbortionError as exc :
321+ if exc .code == StatusCode .ABORTED :
322+ raise Conflict (exc .details )
323+ raise
324+
325+ def rollback (self , project , request_pb ):
326+ """Perform a ``rollback`` request.
327+
328+ :type project: string
329+ :param project: The project to connect to. This is
330+ usually your project name in the cloud console.
331+
332+ :type request_pb: :class:`._generated.datastore_pb2.RollbackRequest`
333+ :param request_pb: The request protobuf object.
334+
335+ :rtype: :class:`._generated.datastore_pb2.RollbackResponse`
336+ :returns: The returned protobuf response object.
337+ """
338+ request_pb .project_id = project
339+ return self ._stub .Rollback (request_pb , GRPC_TIMEOUT_SECONDS )
340+
341+ def allocate_ids (self , project , request_pb ):
342+ """Perform an ``allocateIds`` request.
343+
344+ :type project: string
345+ :param project: The project to connect to. This is
346+ usually your project name in the cloud console.
347+
348+ :type request_pb: :class:`._generated.datastore_pb2.AllocateIdsRequest`
349+ :param request_pb: The request protobuf object.
350+
351+ :rtype: :class:`._generated.datastore_pb2.AllocateIdsResponse`
352+ :returns: The returned protobuf response object.
353+ """
354+ request_pb .project_id = project
355+ return self ._stub .AllocateIds (request_pb , GRPC_TIMEOUT_SECONDS )
356+
357+
199358class Connection (connection_module .Connection ):
200359 """A connection to the Google Cloud Datastore via the Protobuf API.
201360
@@ -213,7 +372,7 @@ class Connection(connection_module.Connection):
213372 :attr:`API_BASE_URL`.
214373 """
215374
216- API_BASE_URL = 'https://datastore.googleapis.com'
375+ API_BASE_URL = 'https://' + DATASTORE_API_HOST
217376 """The base of the API call URL."""
218377
219378 API_VERSION = 'v1beta3'
@@ -236,7 +395,10 @@ def __init__(self, credentials=None, http=None, api_base_url=None):
236395 except KeyError :
237396 api_base_url = self .__class__ .API_BASE_URL
238397 self .api_base_url = api_base_url
239- self ._datastore_api = _DatastoreAPIOverHttp (self )
398+ if _HAVE_GRPC :
399+ self ._datastore_api = _DatastoreAPIOverGRPC (self )
400+ else :
401+ self ._datastore_api = _DatastoreAPIOverHttp (self )
240402
241403 def build_api_url (self , project , method , base_url = None ,
242404 api_version = None ):
0 commit comments