1616
1717import os
1818
19- from gcloud import connection
19+ from google .rpc import status_pb2
20+
21+ from gcloud import connection as connection_module
2022from gcloud .environment_vars import GCD_HOST
2123from gcloud .exceptions import make_exception
2224from gcloud .datastore ._generated import datastore_pb2 as _datastore_pb2
23- from google .rpc import status_pb2
24-
2525
26- class Connection (connection .Connection ):
27- """A connection to the Google Cloud Datastore via the Protobuf API.
28-
29- This class should understand only the basic types (and protobufs)
30- in method arguments, however should be capable of returning advanced types.
3126
32- :type credentials: :class:`oauth2client.client.OAuth2Credentials`
33- :param credentials: The OAuth2 Credentials to use for this connection .
27+ class _DatastoreAPIOverHttp ( object ):
28+ """Helper mapping datastore API methods .
3429
35- :type http: :class:`httplib2.Http` or class that defines ``request()``.
36- :param http: An optional HTTP object to make requests .
30+ Methods make bare API requests without any helpers for constructing
31+ the requests or parsing the responses .
3732
38- :type api_base_url: string
39- :param api_base_url: The base of the API call URL. Defaults to
40- :attr:`API_BASE_URL` .
33+ :type connection: :class:`gcloud.datastore.connection.Connection`
34+ :param connection: A connection object that contains helpful
35+ information for making requests .
4136 """
4237
43- API_BASE_URL = 'https://datastore.googleapis.com'
44- """The base of the API call URL."""
45-
46- API_VERSION = 'v1'
47- """The version of the API, used in building the API call's URL."""
48-
49- API_URL_TEMPLATE = ('{api_base}/{api_version}/projects'
50- '/{project}:{method}' )
51- """A template for the URL of a particular API call."""
52-
53- SCOPE = ('https://www.googleapis.com/auth/datastore' ,)
54- """The scopes required for authenticating as a Cloud Datastore consumer."""
55-
56- def __init__ (self , credentials = None , http = None , api_base_url = None ):
57- super (Connection , self ).__init__ (credentials = credentials , http = http )
58- if api_base_url is None :
59- try :
60- # gcd.sh has /datastore/ in the path still since it supports
61- # v1beta2 and v1beta3 simultaneously.
62- api_base_url = '%s/datastore' % (os .environ [GCD_HOST ],)
63- except KeyError :
64- api_base_url = self .__class__ .API_BASE_URL
65- self .api_base_url = api_base_url
38+ def __init__ (self , connection ):
39+ self .connection = connection
6640
6741 def _request (self , project , method , data ):
6842 """Make a request over the Http transport to the Cloud Datastore API.
@@ -86,10 +60,10 @@ def _request(self, project, method, data):
8660 headers = {
8761 'Content-Type' : 'application/x-protobuf' ,
8862 'Content-Length' : str (len (data )),
89- 'User-Agent' : self .USER_AGENT ,
63+ 'User-Agent' : self .connection . USER_AGENT ,
9064 }
91- headers , content = self .http .request (
92- uri = self .build_api_url (project = project , method = method ),
65+ headers , content = self .connection . http .request (
66+ uri = self .connection . build_api_url (project = project , method = method ),
9367 method = 'POST' , headers = headers , body = data )
9468
9569 status = headers ['status' ]
@@ -124,6 +98,146 @@ def _rpc(self, project, method, request_pb, response_pb_cls):
12498 data = request_pb .SerializeToString ())
12599 return response_pb_cls .FromString (response )
126100
101+ def lookup (self , project , request_pb ):
102+ """Perform a ``lookup`` request.
103+
104+ :type project: string
105+ :param project: The project to connect to. This is
106+ usually your project name in the cloud console.
107+
108+ :type request_pb: :class:`._generated.datastore_pb2.LookupRequest`
109+ :param request_pb: The request protobuf object.
110+
111+ :rtype: :class:`._generated.datastore_pb2.LookupResponse`
112+ :returns: The returned protobuf response object.
113+ """
114+ return self ._rpc (project , 'lookup' , request_pb ,
115+ _datastore_pb2 .LookupResponse )
116+
117+ def run_query (self , project , request_pb ):
118+ """Perform a ``runQuery`` request.
119+
120+ :type project: string
121+ :param project: The project to connect to. This is
122+ usually your project name in the cloud console.
123+
124+ :type request_pb: :class:`._generated.datastore_pb2.RunQueryRequest`
125+ :param request_pb: The request protobuf object.
126+
127+ :rtype: :class:`._generated.datastore_pb2.RunQueryResponse`
128+ :returns: The returned protobuf response object.
129+ """
130+ return self ._rpc (project , 'runQuery' , request_pb ,
131+ _datastore_pb2 .RunQueryResponse )
132+
133+ def begin_transaction (self , project , request_pb ):
134+ """Perform a ``beginTransaction`` request.
135+
136+ :type project: string
137+ :param project: The project to connect to. This is
138+ usually your project name in the cloud console.
139+
140+ :type request_pb:
141+ :class:`._generated.datastore_pb2.BeginTransactionRequest`
142+ :param request_pb: The request protobuf object.
143+
144+ :rtype: :class:`._generated.datastore_pb2.BeginTransactionResponse`
145+ :returns: The returned protobuf response object.
146+ """
147+ return self ._rpc (project , 'beginTransaction' , request_pb ,
148+ _datastore_pb2 .BeginTransactionResponse )
149+
150+ def commit (self , project , request_pb ):
151+ """Perform a ``commit`` request.
152+
153+ :type project: string
154+ :param project: The project to connect to. This is
155+ usually your project name in the cloud console.
156+
157+ :type request_pb: :class:`._generated.datastore_pb2.CommitRequest`
158+ :param request_pb: The request protobuf object.
159+
160+ :rtype: :class:`._generated.datastore_pb2.CommitResponse`
161+ :returns: The returned protobuf response object.
162+ """
163+ return self ._rpc (project , 'commit' , request_pb ,
164+ _datastore_pb2 .CommitResponse )
165+
166+ def rollback (self , project , request_pb ):
167+ """Perform a ``rollback`` request.
168+
169+ :type project: string
170+ :param project: The project to connect to. This is
171+ usually your project name in the cloud console.
172+
173+ :type request_pb: :class:`._generated.datastore_pb2.RollbackRequest`
174+ :param request_pb: The request protobuf object.
175+
176+ :rtype: :class:`._generated.datastore_pb2.RollbackResponse`
177+ :returns: The returned protobuf response object.
178+ """
179+ return self ._rpc (project , 'rollback' , request_pb ,
180+ _datastore_pb2 .RollbackResponse )
181+
182+ def allocate_ids (self , project , request_pb ):
183+ """Perform an ``allocateIds`` request.
184+
185+ :type project: string
186+ :param project: The project to connect to. This is
187+ usually your project name in the cloud console.
188+
189+ :type request_pb: :class:`._generated.datastore_pb2.AllocateIdsRequest`
190+ :param request_pb: The request protobuf object.
191+
192+ :rtype: :class:`._generated.datastore_pb2.AllocateIdsResponse`
193+ :returns: The returned protobuf response object.
194+ """
195+ return self ._rpc (project , 'allocateIds' , request_pb ,
196+ _datastore_pb2 .AllocateIdsResponse )
197+
198+
199+ class Connection (connection_module .Connection ):
200+ """A connection to the Google Cloud Datastore via the Protobuf API.
201+
202+ This class should understand only the basic types (and protobufs)
203+ in method arguments, however should be capable of returning advanced types.
204+
205+ :type credentials: :class:`oauth2client.client.OAuth2Credentials`
206+ :param credentials: The OAuth2 Credentials to use for this connection.
207+
208+ :type http: :class:`httplib2.Http` or class that defines ``request()``.
209+ :param http: An optional HTTP object to make requests.
210+
211+ :type api_base_url: string
212+ :param api_base_url: The base of the API call URL. Defaults to
213+ :attr:`API_BASE_URL`.
214+ """
215+
216+ API_BASE_URL = 'https://datastore.googleapis.com'
217+ """The base of the API call URL."""
218+
219+ API_VERSION = 'v1'
220+ """The version of the API, used in building the API call's URL."""
221+
222+ API_URL_TEMPLATE = ('{api_base}/{api_version}/projects'
223+ '/{project}:{method}' )
224+ """A template for the URL of a particular API call."""
225+
226+ SCOPE = ('https://www.googleapis.com/auth/datastore' ,)
227+ """The scopes required for authenticating as a Cloud Datastore consumer."""
228+
229+ def __init__ (self , credentials = None , http = None , api_base_url = None ):
230+ super (Connection , self ).__init__ (credentials = credentials , http = http )
231+ if api_base_url is None :
232+ try :
233+ # gcd.sh has /datastore/ in the path still since it supports
234+ # v1beta2 and v1beta3 simultaneously.
235+ api_base_url = '%s/datastore' % (os .environ [GCD_HOST ],)
236+ except KeyError :
237+ api_base_url = self .__class__ .API_BASE_URL
238+ self .api_base_url = api_base_url
239+ self ._datastore_api = _DatastoreAPIOverHttp (self )
240+
127241 def build_api_url (self , project , method , base_url = None ,
128242 api_version = None ):
129243 """Construct the URL for a particular API call.
@@ -205,8 +319,7 @@ def lookup(self, project, key_pbs,
205319 _set_read_options (lookup_request , eventual , transaction_id )
206320 _add_keys_to_request (lookup_request .keys , key_pbs )
207321
208- lookup_response = self ._rpc (project , 'lookup' , lookup_request ,
209- _datastore_pb2 .LookupResponse )
322+ lookup_response = self ._datastore_api .lookup (project , lookup_request )
210323
211324 results = [result .entity for result in lookup_response .found ]
212325 missing = [result .entity for result in lookup_response .missing ]
@@ -260,8 +373,7 @@ def run_query(self, project, query_pb, namespace=None,
260373 request .partition_id .namespace_id = namespace
261374
262375 request .query .CopyFrom (query_pb )
263- response = self ._rpc (project , 'runQuery' , request ,
264- _datastore_pb2 .RunQueryResponse )
376+ response = self ._datastore_api .run_query (project , request )
265377 return (
266378 [e .entity for e in response .batch .entity_results ],
267379 response .batch .end_cursor , # Assume response always has cursor.
@@ -281,8 +393,7 @@ def begin_transaction(self, project):
281393 :returns: The serialized transaction that was begun.
282394 """
283395 request = _datastore_pb2 .BeginTransactionRequest ()
284- response = self ._rpc (project , 'beginTransaction' , request ,
285- _datastore_pb2 .BeginTransactionResponse )
396+ response = self ._datastore_api .begin_transaction (project , request )
286397 return response .transaction
287398
288399 def commit (self , project , request , transaction_id ):
@@ -316,8 +427,7 @@ def commit(self, project, request, transaction_id):
316427 else :
317428 request .mode = _datastore_pb2 .CommitRequest .NON_TRANSACTIONAL
318429
319- response = self ._rpc (project , 'commit' , request ,
320- _datastore_pb2 .CommitResponse )
430+ response = self ._datastore_api .commit (project , request )
321431 return _parse_commit_response (response )
322432
323433 def rollback (self , project , transaction_id ):
@@ -335,8 +445,7 @@ def rollback(self, project, transaction_id):
335445 request = _datastore_pb2 .RollbackRequest ()
336446 request .transaction = transaction_id
337447 # Nothing to do with this response, so just execute the method.
338- self ._rpc (project , 'rollback' , request ,
339- _datastore_pb2 .RollbackResponse )
448+ self ._datastore_api .rollback (project , request )
340449
341450 def allocate_ids (self , project , key_pbs ):
342451 """Obtain backend-generated IDs for a set of keys.
@@ -356,8 +465,7 @@ def allocate_ids(self, project, key_pbs):
356465 request = _datastore_pb2 .AllocateIdsRequest ()
357466 _add_keys_to_request (request .keys , key_pbs )
358467 # Nothing to do with this response, so just execute the method.
359- response = self ._rpc (project , 'allocateIds' , request ,
360- _datastore_pb2 .AllocateIdsResponse )
468+ response = self ._datastore_api .allocate_ids (project , request )
361469 return list (response .keys )
362470
363471
0 commit comments