Skip to content

Commit b9aaf10

Browse files
committed
Making datastore api_base_url set in Connection constructor.
This avoids setting anything at import time.
1 parent d2aaab8 commit b9aaf10

File tree

5 files changed

+82
-67
lines changed

5 files changed

+82
-67
lines changed

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/connection.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ class Connection(connection.Connection):
3333
3434
:type credentials: :class:`oauth2client.client.OAuth2Credentials`
3535
:param credentials: The OAuth2 Credentials to use for this connection.
36-
"""
3736
38-
API_BASE_URL = os.getenv(_GCD_HOST_ENV_VAR_NAME,
39-
connection.Connection.API_BASE_URL)
40-
"""The base of the API call URL."""
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`.
40+
"""
4141

4242
API_VERSION = 'v1beta2'
4343
"""The version of the API, used in building the API call's URL."""
@@ -46,6 +46,13 @@ class Connection(connection.Connection):
4646
'/datasets/{dataset_id}/{method}')
4747
"""A template for the URL of a particular API call."""
4848

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+
4956
def _request(self, dataset_id, method, data):
5057
"""Make a request over the Http transport to the Cloud Datastore API.
5158
@@ -102,8 +109,7 @@ def _rpc(self, dataset_id, method, request_pb, response_pb_cls):
102109
data=request_pb.SerializeToString())
103110
return response_pb_cls.FromString(response)
104111

105-
@classmethod
106-
def build_api_url(cls, dataset_id, method, base_url=None,
112+
def build_api_url(self, dataset_id, method, base_url=None,
107113
api_version=None):
108114
"""Construct the URL for a particular API call.
109115
@@ -125,9 +131,9 @@ def build_api_url(cls, dataset_id, method, base_url=None,
125131
:param api_version: The version of the API to connect to.
126132
You shouldn't have to provide this.
127133
"""
128-
return cls.API_URL_TEMPLATE.format(
129-
api_base=(base_url or cls.API_BASE_URL),
130-
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),
131137
dataset_id=dataset_id, method=method)
132138

133139
def lookup(self, dataset_id, key_pbs,

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',

gcloud/datastore/test_connection.py

Lines changed: 57 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -47,45 +47,50 @@ def _verifyProtobufCall(self, called_with, URI, conn):
4747
conn.USER_AGENT)
4848

4949
def test_default_url(self):
50-
from gcloud.connection import Connection
50+
from gcloud.connection import API_BASE_URL
5151

52-
klass = self._getTargetClass()
53-
self.assertEqual(klass.API_BASE_URL, Connection.API_BASE_URL)
52+
conn = self._makeOne()
53+
self.assertEqual(conn.api_base_url, API_BASE_URL)
5454

55-
def test_custom_url(self):
55+
def test_custom_url_from_env(self):
5656
import os
57-
import sys
5857
from gcloud._testing import _Monkey
59-
from gcloud.connection import Connection as BaseConnection
58+
from gcloud.connection import API_BASE_URL
6059
from gcloud.datastore.connection import _GCD_HOST_ENV_VAR_NAME
6160

6261
HOST = object()
6362
fake_environ = {_GCD_HOST_ENV_VAR_NAME: HOST}
6463

65-
def fake_getenv(key, default_val=None):
66-
return fake_environ.get(key, default_val)
64+
with _Monkey(os, getenv=fake_environ.get):
65+
conn = self._makeOne()
6766

68-
# We want to temporarily all the gcloud.datastore modules except for
69-
# the gcloud.datastore package itself. Then re-import.
70-
gcloud_keys = [key for key in sys.modules
71-
if 'gcloud.datastore.' in key]
72-
modules_as_is = sys.modules.copy()
73-
try:
74-
for key in gcloud_keys:
75-
sys.modules.pop(key)
67+
self.assertNotEqual(conn.api_base_url, API_BASE_URL)
68+
self.assertEqual(conn.api_base_url, HOST)
7669

77-
with _Monkey(os, getenv=fake_getenv):
78-
from gcloud.datastore.connection import Connection
79-
finally:
80-
sys.modules.update(modules_as_is)
70+
def test_custom_url_from_constructor(self):
71+
from gcloud.connection import API_BASE_URL
8172

82-
self.assertNotEqual(Connection.API_BASE_URL,
83-
BaseConnection.API_BASE_URL)
84-
self.assertEqual(Connection.API_BASE_URL, HOST)
73+
HOST = object()
74+
conn = self._makeOne(api_base_url=HOST)
75+
self.assertNotEqual(conn.api_base_url, API_BASE_URL)
76+
self.assertEqual(conn.api_base_url, HOST)
8577

86-
# Make sure the restored import.
87-
from gcloud.datastore.connection import Connection
88-
self.assertEqual(Connection.API_BASE_URL, BaseConnection.API_BASE_URL)
78+
def test_custom_url_constructor_and_env(self):
79+
import os
80+
from gcloud._testing import _Monkey
81+
from gcloud.connection import API_BASE_URL
82+
from gcloud.datastore.connection import _GCD_HOST_ENV_VAR_NAME
83+
84+
HOST1 = object()
85+
HOST2 = object()
86+
fake_environ = {_GCD_HOST_ENV_VAR_NAME: HOST1}
87+
88+
with _Monkey(os, getenv=fake_environ.get):
89+
conn = self._makeOne(api_base_url=HOST2)
90+
91+
self.assertNotEqual(conn.api_base_url, API_BASE_URL)
92+
self.assertNotEqual(conn.api_base_url, HOST1)
93+
self.assertEqual(conn.api_base_url, HOST2)
8994

9095
def test_ctor_defaults(self):
9196
conn = self._makeOne()
@@ -128,7 +133,7 @@ def test__request_w_200(self):
128133
DATA = b'DATA'
129134
conn = self._makeOne()
130135
URI = '/'.join([
131-
conn.API_BASE_URL,
136+
conn.api_base_url,
132137
'datastore',
133138
conn.API_VERSION,
134139
'datasets',
@@ -174,7 +179,7 @@ def FromString(cls, pb):
174179
METHOD = 'METHOD'
175180
conn = self._makeOne()
176181
URI = '/'.join([
177-
conn.API_BASE_URL,
182+
conn.api_base_url,
178183
'datastore',
179184
conn.API_VERSION,
180185
'datasets',
@@ -191,23 +196,23 @@ def FromString(cls, pb):
191196
def test_build_api_url_w_default_base_version(self):
192197
DATASET_ID = 'DATASET'
193198
METHOD = 'METHOD'
194-
klass = self._getTargetClass()
199+
conn = self._makeOne()
195200
URI = '/'.join([
196-
klass.API_BASE_URL,
201+
conn.api_base_url,
197202
'datastore',
198-
klass.API_VERSION,
203+
conn.API_VERSION,
199204
'datasets',
200205
DATASET_ID,
201206
METHOD,
202207
])
203-
self.assertEqual(klass.build_api_url(DATASET_ID, METHOD), URI)
208+
self.assertEqual(conn.build_api_url(DATASET_ID, METHOD), URI)
204209

205210
def test_build_api_url_w_explicit_base_version(self):
206211
BASE = 'http://example.com/'
207212
VER = '3.1415926'
208213
DATASET_ID = 'DATASET'
209214
METHOD = 'METHOD'
210-
klass = self._getTargetClass()
215+
conn = self._makeOne()
211216
URI = '/'.join([
212217
BASE,
213218
'datastore',
@@ -216,7 +221,7 @@ def test_build_api_url_w_explicit_base_version(self):
216221
DATASET_ID,
217222
METHOD,
218223
])
219-
self.assertEqual(klass.build_api_url(DATASET_ID, METHOD, BASE, VER),
224+
self.assertEqual(conn.build_api_url(DATASET_ID, METHOD, BASE, VER),
220225
URI)
221226

222227
def test_lookup_single_key_empty_response(self):
@@ -227,7 +232,7 @@ def test_lookup_single_key_empty_response(self):
227232
rsp_pb = datastore_pb.LookupResponse()
228233
conn = self._makeOne()
229234
URI = '/'.join([
230-
conn.API_BASE_URL,
235+
conn.api_base_url,
231236
'datastore',
232237
conn.API_VERSION,
233238
'datasets',
@@ -256,7 +261,7 @@ def test_lookup_single_key_empty_response_w_eventual(self):
256261
rsp_pb = datastore_pb.LookupResponse()
257262
conn = self._makeOne()
258263
URI = '/'.join([
259-
conn.API_BASE_URL,
264+
conn.api_base_url,
260265
'datastore',
261266
conn.API_VERSION,
262267
'datasets',
@@ -298,7 +303,7 @@ def test_lookup_single_key_empty_response_w_transaction(self):
298303
rsp_pb = datastore_pb.LookupResponse()
299304
conn = self._makeOne()
300305
URI = '/'.join([
301-
conn.API_BASE_URL,
306+
conn.api_base_url,
302307
'datastore',
303308
conn.API_VERSION,
304309
'datasets',
@@ -332,7 +337,7 @@ def test_lookup_single_key_nonempty_response(self):
332337
rsp_pb.found.add(entity=entity)
333338
conn = self._makeOne()
334339
URI = '/'.join([
335-
conn.API_BASE_URL,
340+
conn.api_base_url,
336341
'datastore',
337342
conn.API_VERSION,
338343
'datasets',
@@ -363,7 +368,7 @@ def test_lookup_multiple_keys_empty_response(self):
363368
rsp_pb = datastore_pb.LookupResponse()
364369
conn = self._makeOne()
365370
URI = '/'.join([
366-
conn.API_BASE_URL,
371+
conn.api_base_url,
367372
'datastore',
368373
conn.API_VERSION,
369374
'datasets',
@@ -398,7 +403,7 @@ def test_lookup_multiple_keys_w_missing(self):
398403
er_2.entity.key.CopyFrom(key_pb2)
399404
conn = self._makeOne()
400405
URI = '/'.join([
401-
conn.API_BASE_URL,
406+
conn.api_base_url,
402407
'datastore',
403408
conn.API_VERSION,
404409
'datasets',
@@ -432,7 +437,7 @@ def test_lookup_multiple_keys_w_deferred(self):
432437
rsp_pb.deferred.add().CopyFrom(key_pb2)
433438
conn = self._makeOne()
434439
URI = '/'.join([
435-
conn.API_BASE_URL,
440+
conn.api_base_url,
436441
'datastore',
437442
conn.API_VERSION,
438443
'datasets',
@@ -473,7 +478,7 @@ def test_run_query_w_eventual_no_transaction(self):
473478
rsp_pb.batch.entity_result_type = datastore_pb.EntityResult.FULL
474479
conn = self._makeOne()
475480
URI = '/'.join([
476-
conn.API_BASE_URL,
481+
conn.api_base_url,
477482
'datastore',
478483
conn.API_VERSION,
479484
'datasets',
@@ -513,7 +518,7 @@ def test_run_query_wo_eventual_w_transaction(self):
513518
rsp_pb.batch.entity_result_type = datastore_pb.EntityResult.FULL
514519
conn = self._makeOne()
515520
URI = '/'.join([
516-
conn.API_BASE_URL,
521+
conn.api_base_url,
517522
'datastore',
518523
conn.API_VERSION,
519524
'datasets',
@@ -569,7 +574,7 @@ def test_run_query_wo_namespace_empty_result(self):
569574
rsp_pb.batch.entity_result_type = datastore_pb.EntityResult.FULL
570575
conn = self._makeOne()
571576
URI = '/'.join([
572-
conn.API_BASE_URL,
577+
conn.api_base_url,
573578
'datastore',
574579
conn.API_VERSION,
575580
'datasets',
@@ -603,7 +608,7 @@ def test_run_query_w_namespace_nonempty_result(self):
603608
rsp_pb.batch.more_results = 3 # NO_MORE_RESULTS
604609
conn = self._makeOne()
605610
URI = '/'.join([
606-
conn.API_BASE_URL,
611+
conn.api_base_url,
607612
'datastore',
608613
conn.API_VERSION,
609614
'datasets',
@@ -630,7 +635,7 @@ def test_begin_transaction_default_serialize(self):
630635
rsp_pb.transaction = TRANSACTION
631636
conn = self._makeOne()
632637
URI = '/'.join([
633-
conn.API_BASE_URL,
638+
conn.api_base_url,
634639
'datastore',
635640
conn.API_VERSION,
636641
'datasets',
@@ -655,7 +660,7 @@ def test_begin_transaction_explicit_serialize(self):
655660
rsp_pb.transaction = TRANSACTION
656661
conn = self._makeOne()
657662
URI = '/'.join([
658-
conn.API_BASE_URL,
663+
conn.api_base_url,
659664
'datastore',
660665
conn.API_VERSION,
661666
'datasets',
@@ -685,7 +690,7 @@ def test_commit_wo_transaction(self):
685690
prop.value.string_value = u'Foo'
686691
conn = self._makeOne()
687692
URI = '/'.join([
688-
conn.API_BASE_URL,
693+
conn.api_base_url,
689694
'datastore',
690695
conn.API_VERSION,
691696
'datasets',
@@ -719,7 +724,7 @@ def test_commit_w_transaction(self):
719724
prop.value.string_value = u'Foo'
720725
conn = self._makeOne()
721726
URI = '/'.join([
722-
conn.API_BASE_URL,
727+
conn.api_base_url,
723728
'datastore',
724729
conn.API_VERSION,
725730
'datasets',
@@ -747,7 +752,7 @@ def test_rollback_ok(self):
747752
rsp_pb = datastore_pb.RollbackResponse()
748753
conn = self._makeOne()
749754
URI = '/'.join([
750-
conn.API_BASE_URL,
755+
conn.api_base_url,
751756
'datastore',
752757
conn.API_VERSION,
753758
'datasets',
@@ -770,7 +775,7 @@ def test_allocate_ids_empty(self):
770775
rsp_pb = datastore_pb.AllocateIdsResponse()
771776
conn = self._makeOne()
772777
URI = '/'.join([
773-
conn.API_BASE_URL,
778+
conn.api_base_url,
774779
'datastore',
775780
conn.API_VERSION,
776781
'datasets',
@@ -803,7 +808,7 @@ def test_allocate_ids_non_empty(self):
803808
rsp_pb.key.add().CopyFrom(after_key_pbs[1])
804809
conn = self._makeOne()
805810
URI = '/'.join([
806-
conn.API_BASE_URL,
811+
conn.api_base_url,
807812
'datastore',
808813
conn.API_VERSION,
809814
'datasets',

0 commit comments

Comments
 (0)