Skip to content

Commit f56abdf

Browse files
committed
Merge pull request #656 from dhermes/fix-650
Adding support for GCD dev server in datastore package.
2 parents 018b467 + b9aaf10 commit f56abdf

7 files changed

Lines changed: 157 additions & 39 deletions

File tree

gcloud/connection.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
import httplib2
2020

2121

22+
API_BASE_URL = 'https://www.googleapis.com'
23+
"""The base of the API call URL."""
24+
25+
2226
class Connection(object):
2327
"""A generic connection to Google Cloud Platform.
2428
@@ -54,9 +58,6 @@ class Connection(object):
5458
:param http: An optional HTTP object to make requests.
5559
"""
5660

57-
API_BASE_URL = 'https://www.googleapis.com'
58-
"""The base of the API call URL."""
59-
6061
USER_AGENT = "gcloud-python/{0}".format(get_distribution('gcloud').version)
6162
"""The user agent for gcloud-python requests."""
6263

gcloud/datastore/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
"""The scopes required for authenticating as a Cloud Datastore consumer."""
6868

6969
_DATASET_ENV_VAR_NAME = 'GCLOUD_DATASET_ID'
70+
_GCD_DATASET_ENV_VAR_NAME = 'DATASTORE_DATASET'
7071

7172

7273
def set_default_dataset_id(dataset_id=None):
@@ -86,6 +87,9 @@ def set_default_dataset_id(dataset_id=None):
8687
if dataset_id is None:
8788
dataset_id = os.getenv(_DATASET_ENV_VAR_NAME)
8889

90+
if dataset_id is None:
91+
dataset_id = os.getenv(_GCD_DATASET_ENV_VAR_NAME)
92+
8993
if dataset_id is None:
9094
dataset_id = _implicit_environ.app_engine_id()
9195

gcloud/datastore/connection.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,17 @@
1414

1515
"""Connections to gcloud datastore API servers."""
1616

17+
import os
18+
1719
from gcloud import connection
1820
from gcloud.exceptions import make_exception
1921
from gcloud.datastore import _datastore_v1_pb2 as datastore_pb
2022
from gcloud.datastore import helpers
2123

2224

25+
_GCD_HOST_ENV_VAR_NAME = 'DATASTORE_HOST'
26+
27+
2328
class Connection(connection.Connection):
2429
"""A connection to the Google Cloud Datastore via the Protobuf API.
2530
@@ -28,6 +33,10 @@ class Connection(connection.Connection):
2833
2934
:type credentials: :class:`oauth2client.client.OAuth2Credentials`
3035
:param credentials: The OAuth2 Credentials to use for this connection.
36+
37+
:type api_base_url: string
38+
:param api_base_url: The base of the API call URL. Defaults to the value
39+
from :mod:`gcloud.connection`.
3140
"""
3241

3342
API_VERSION = 'v1beta2'
@@ -37,6 +46,13 @@ class Connection(connection.Connection):
3746
'/datasets/{dataset_id}/{method}')
3847
"""A template for the URL of a particular API call."""
3948

49+
def __init__(self, credentials=None, http=None, api_base_url=None):
50+
super(Connection, self).__init__(credentials=credentials, http=http)
51+
if api_base_url is None:
52+
api_base_url = os.getenv(_GCD_HOST_ENV_VAR_NAME,
53+
connection.API_BASE_URL)
54+
self.api_base_url = api_base_url
55+
4056
def _request(self, dataset_id, method, data):
4157
"""Make a request over the Http transport to the Cloud Datastore API.
4258
@@ -93,8 +109,7 @@ def _rpc(self, dataset_id, method, request_pb, response_pb_cls):
93109
data=request_pb.SerializeToString())
94110
return response_pb_cls.FromString(response)
95111

96-
@classmethod
97-
def build_api_url(cls, dataset_id, method, base_url=None,
112+
def build_api_url(self, dataset_id, method, base_url=None,
98113
api_version=None):
99114
"""Construct the URL for a particular API call.
100115
@@ -116,9 +131,9 @@ def build_api_url(cls, dataset_id, method, base_url=None,
116131
:param api_version: The version of the API to connect to.
117132
You shouldn't have to provide this.
118133
"""
119-
return cls.API_URL_TEMPLATE.format(
120-
api_base=(base_url or cls.API_BASE_URL),
121-
api_version=(api_version or cls.API_VERSION),
134+
return self.API_URL_TEMPLATE.format(
135+
api_base=(base_url or self.api_base_url),
136+
api_version=(api_version or self.API_VERSION),
122137
dataset_id=dataset_id, method=method)
123138

124139
def lookup(self, dataset_id, key_pbs,

gcloud/datastore/test___init__.py

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ def _callFUT(self, dataset_id=None):
3030
from gcloud.datastore import set_default_dataset_id
3131
return set_default_dataset_id(dataset_id=dataset_id)
3232

33-
def _monkeyEnviron(self, implicit_dataset_id):
33+
def _monkeyEnviron(self, implicit_dataset_id, environ=None):
3434
import os
3535
from gcloud._testing import _Monkey
3636
from gcloud.datastore import _DATASET_ENV_VAR_NAME
37-
environ = {_DATASET_ENV_VAR_NAME: implicit_dataset_id}
37+
environ = environ or {_DATASET_ENV_VAR_NAME: implicit_dataset_id}
3838
return _Monkey(os, getenv=environ.get)
3939

4040
def _monkeyImplicit(self, connection=None, app_identity=None):
@@ -112,6 +112,55 @@ def test_set_explicit_None_w_env_var_set(self):
112112

113113
self.assertEqual(_implicit_environ.DATASET_ID, IMPLICIT_DATASET_ID)
114114

115+
def test_set_from_gcd_env_var(self):
116+
from gcloud.datastore import _GCD_DATASET_ENV_VAR_NAME
117+
from gcloud.datastore import _implicit_environ
118+
119+
GCD_DATASET_ID = 'GCD-IMPLICIT'
120+
ENVIRON = {_GCD_DATASET_ENV_VAR_NAME: GCD_DATASET_ID}
121+
122+
with self._monkeyEnviron(None, environ=ENVIRON):
123+
with self._monkeyImplicit():
124+
self._callFUT()
125+
126+
self.assertEqual(_implicit_environ.DATASET_ID, GCD_DATASET_ID)
127+
128+
def test_set_gcd_and_production_env_vars(self):
129+
from gcloud.datastore import _DATASET_ENV_VAR_NAME
130+
from gcloud.datastore import _GCD_DATASET_ENV_VAR_NAME
131+
from gcloud.datastore import _implicit_environ
132+
133+
IMPLICIT_DATASET_ID = 'IMPLICIT'
134+
GCD_DATASET_ID = 'GCD-IMPLICIT'
135+
ENVIRON = {
136+
_DATASET_ENV_VAR_NAME: IMPLICIT_DATASET_ID,
137+
_GCD_DATASET_ENV_VAR_NAME: GCD_DATASET_ID,
138+
}
139+
140+
with self._monkeyEnviron(None, environ=ENVIRON):
141+
with self._monkeyImplicit():
142+
self._callFUT()
143+
144+
self.assertNotEqual(_implicit_environ.DATASET_ID, GCD_DATASET_ID)
145+
self.assertEqual(_implicit_environ.DATASET_ID, IMPLICIT_DATASET_ID)
146+
147+
def test_set_gcd_env_vars_and_appengine(self):
148+
from gcloud.datastore import _GCD_DATASET_ENV_VAR_NAME
149+
from gcloud.datastore import _implicit_environ
150+
151+
GCD_DATASET_ID = 'GCD-IMPLICIT'
152+
ENVIRON = {_GCD_DATASET_ENV_VAR_NAME: GCD_DATASET_ID}
153+
154+
APP_ENGINE_ID = 'GAE'
155+
APP_IDENTITY = _AppIdentity(APP_ENGINE_ID)
156+
157+
with self._monkeyEnviron(None, environ=ENVIRON):
158+
with self._monkeyImplicit(app_identity=APP_IDENTITY):
159+
self._callFUT()
160+
161+
self.assertNotEqual(_implicit_environ.DATASET_ID, APP_ENGINE_ID)
162+
self.assertEqual(_implicit_environ.DATASET_ID, GCD_DATASET_ID)
163+
115164
def test_set_implicit_from_appengine(self):
116165
from gcloud.datastore import _implicit_environ
117166

gcloud/datastore/test_api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ def test_w_deferred_from_backend_but_not_passed(self):
359359

360360
# Make URI to check for requests.
361361
URI = '/'.join([
362-
conn.API_BASE_URL,
362+
conn.api_base_url,
363363
'datastore',
364364
conn.API_VERSION,
365365
'datasets',

0 commit comments

Comments
 (0)