Skip to content

Commit

Permalink
Making datastore api_base_url set in Connection constructor.
Browse files Browse the repository at this point in the history
This avoids setting anything at import time.
  • Loading branch information
dhermes committed Feb 18, 2015
1 parent d2aaab8 commit b9aaf10
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 67 deletions.
7 changes: 4 additions & 3 deletions gcloud/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
import httplib2


API_BASE_URL = 'https://www.googleapis.com'
"""The base of the API call URL."""


class Connection(object):
"""A generic connection to Google Cloud Platform.
Expand Down Expand Up @@ -54,9 +58,6 @@ class Connection(object):
:param http: An optional HTTP object to make requests.
"""

API_BASE_URL = 'https://www.googleapis.com'
"""The base of the API call URL."""

USER_AGENT = "gcloud-python/{0}".format(get_distribution('gcloud').version)
"""The user agent for gcloud-python requests."""

Expand Down
24 changes: 15 additions & 9 deletions gcloud/datastore/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ class Connection(connection.Connection):
:type credentials: :class:`oauth2client.client.OAuth2Credentials`
:param credentials: The OAuth2 Credentials to use for this connection.
"""
API_BASE_URL = os.getenv(_GCD_HOST_ENV_VAR_NAME,
connection.Connection.API_BASE_URL)
"""The base of the API call URL."""
:type api_base_url: string
:param api_base_url: The base of the API call URL. Defaults to the value
from :mod:`gcloud.connection`.
"""

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

def __init__(self, credentials=None, http=None, api_base_url=None):
super(Connection, self).__init__(credentials=credentials, http=http)
if api_base_url is None:
api_base_url = os.getenv(_GCD_HOST_ENV_VAR_NAME,
connection.API_BASE_URL)
self.api_base_url = api_base_url

def _request(self, dataset_id, method, data):
"""Make a request over the Http transport to the Cloud Datastore API.
Expand Down Expand Up @@ -102,8 +109,7 @@ def _rpc(self, dataset_id, method, request_pb, response_pb_cls):
data=request_pb.SerializeToString())
return response_pb_cls.FromString(response)

@classmethod
def build_api_url(cls, dataset_id, method, base_url=None,
def build_api_url(self, dataset_id, method, base_url=None,
api_version=None):
"""Construct the URL for a particular API call.
Expand All @@ -125,9 +131,9 @@ def build_api_url(cls, dataset_id, method, base_url=None,
:param api_version: The version of the API to connect to.
You shouldn't have to provide this.
"""
return cls.API_URL_TEMPLATE.format(
api_base=(base_url or cls.API_BASE_URL),
api_version=(api_version or cls.API_VERSION),
return self.API_URL_TEMPLATE.format(
api_base=(base_url or self.api_base_url),
api_version=(api_version or self.API_VERSION),
dataset_id=dataset_id, method=method)

def lookup(self, dataset_id, key_pbs,
Expand Down
2 changes: 1 addition & 1 deletion gcloud/datastore/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ def test_w_deferred_from_backend_but_not_passed(self):

# Make URI to check for requests.
URI = '/'.join([
conn.API_BASE_URL,
conn.api_base_url,
'datastore',
conn.API_VERSION,
'datasets',
Expand Down
109 changes: 57 additions & 52 deletions gcloud/datastore/test_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,45 +47,50 @@ def _verifyProtobufCall(self, called_with, URI, conn):
conn.USER_AGENT)

def test_default_url(self):
from gcloud.connection import Connection
from gcloud.connection import API_BASE_URL

klass = self._getTargetClass()
self.assertEqual(klass.API_BASE_URL, Connection.API_BASE_URL)
conn = self._makeOne()
self.assertEqual(conn.api_base_url, API_BASE_URL)

def test_custom_url(self):
def test_custom_url_from_env(self):
import os
import sys
from gcloud._testing import _Monkey
from gcloud.connection import Connection as BaseConnection
from gcloud.connection import API_BASE_URL
from gcloud.datastore.connection import _GCD_HOST_ENV_VAR_NAME

HOST = object()
fake_environ = {_GCD_HOST_ENV_VAR_NAME: HOST}

def fake_getenv(key, default_val=None):
return fake_environ.get(key, default_val)
with _Monkey(os, getenv=fake_environ.get):
conn = self._makeOne()

# We want to temporarily all the gcloud.datastore modules except for
# the gcloud.datastore package itself. Then re-import.
gcloud_keys = [key for key in sys.modules
if 'gcloud.datastore.' in key]
modules_as_is = sys.modules.copy()
try:
for key in gcloud_keys:
sys.modules.pop(key)
self.assertNotEqual(conn.api_base_url, API_BASE_URL)
self.assertEqual(conn.api_base_url, HOST)

with _Monkey(os, getenv=fake_getenv):
from gcloud.datastore.connection import Connection
finally:
sys.modules.update(modules_as_is)
def test_custom_url_from_constructor(self):
from gcloud.connection import API_BASE_URL

self.assertNotEqual(Connection.API_BASE_URL,
BaseConnection.API_BASE_URL)
self.assertEqual(Connection.API_BASE_URL, HOST)
HOST = object()
conn = self._makeOne(api_base_url=HOST)
self.assertNotEqual(conn.api_base_url, API_BASE_URL)
self.assertEqual(conn.api_base_url, HOST)

# Make sure the restored import.
from gcloud.datastore.connection import Connection
self.assertEqual(Connection.API_BASE_URL, BaseConnection.API_BASE_URL)
def test_custom_url_constructor_and_env(self):
import os
from gcloud._testing import _Monkey
from gcloud.connection import API_BASE_URL
from gcloud.datastore.connection import _GCD_HOST_ENV_VAR_NAME

HOST1 = object()
HOST2 = object()
fake_environ = {_GCD_HOST_ENV_VAR_NAME: HOST1}

with _Monkey(os, getenv=fake_environ.get):
conn = self._makeOne(api_base_url=HOST2)

self.assertNotEqual(conn.api_base_url, API_BASE_URL)
self.assertNotEqual(conn.api_base_url, HOST1)
self.assertEqual(conn.api_base_url, HOST2)

def test_ctor_defaults(self):
conn = self._makeOne()
Expand Down Expand Up @@ -128,7 +133,7 @@ def test__request_w_200(self):
DATA = b'DATA'
conn = self._makeOne()
URI = '/'.join([
conn.API_BASE_URL,
conn.api_base_url,
'datastore',
conn.API_VERSION,
'datasets',
Expand Down Expand Up @@ -174,7 +179,7 @@ def FromString(cls, pb):
METHOD = 'METHOD'
conn = self._makeOne()
URI = '/'.join([
conn.API_BASE_URL,
conn.api_base_url,
'datastore',
conn.API_VERSION,
'datasets',
Expand All @@ -191,23 +196,23 @@ def FromString(cls, pb):
def test_build_api_url_w_default_base_version(self):
DATASET_ID = 'DATASET'
METHOD = 'METHOD'
klass = self._getTargetClass()
conn = self._makeOne()
URI = '/'.join([
klass.API_BASE_URL,
conn.api_base_url,
'datastore',
klass.API_VERSION,
conn.API_VERSION,
'datasets',
DATASET_ID,
METHOD,
])
self.assertEqual(klass.build_api_url(DATASET_ID, METHOD), URI)
self.assertEqual(conn.build_api_url(DATASET_ID, METHOD), URI)

def test_build_api_url_w_explicit_base_version(self):
BASE = 'http://example.com/'
VER = '3.1415926'
DATASET_ID = 'DATASET'
METHOD = 'METHOD'
klass = self._getTargetClass()
conn = self._makeOne()
URI = '/'.join([
BASE,
'datastore',
Expand All @@ -216,7 +221,7 @@ def test_build_api_url_w_explicit_base_version(self):
DATASET_ID,
METHOD,
])
self.assertEqual(klass.build_api_url(DATASET_ID, METHOD, BASE, VER),
self.assertEqual(conn.build_api_url(DATASET_ID, METHOD, BASE, VER),
URI)

def test_lookup_single_key_empty_response(self):
Expand All @@ -227,7 +232,7 @@ def test_lookup_single_key_empty_response(self):
rsp_pb = datastore_pb.LookupResponse()
conn = self._makeOne()
URI = '/'.join([
conn.API_BASE_URL,
conn.api_base_url,
'datastore',
conn.API_VERSION,
'datasets',
Expand Down Expand Up @@ -256,7 +261,7 @@ def test_lookup_single_key_empty_response_w_eventual(self):
rsp_pb = datastore_pb.LookupResponse()
conn = self._makeOne()
URI = '/'.join([
conn.API_BASE_URL,
conn.api_base_url,
'datastore',
conn.API_VERSION,
'datasets',
Expand Down Expand Up @@ -298,7 +303,7 @@ def test_lookup_single_key_empty_response_w_transaction(self):
rsp_pb = datastore_pb.LookupResponse()
conn = self._makeOne()
URI = '/'.join([
conn.API_BASE_URL,
conn.api_base_url,
'datastore',
conn.API_VERSION,
'datasets',
Expand Down Expand Up @@ -332,7 +337,7 @@ def test_lookup_single_key_nonempty_response(self):
rsp_pb.found.add(entity=entity)
conn = self._makeOne()
URI = '/'.join([
conn.API_BASE_URL,
conn.api_base_url,
'datastore',
conn.API_VERSION,
'datasets',
Expand Down Expand Up @@ -363,7 +368,7 @@ def test_lookup_multiple_keys_empty_response(self):
rsp_pb = datastore_pb.LookupResponse()
conn = self._makeOne()
URI = '/'.join([
conn.API_BASE_URL,
conn.api_base_url,
'datastore',
conn.API_VERSION,
'datasets',
Expand Down Expand Up @@ -398,7 +403,7 @@ def test_lookup_multiple_keys_w_missing(self):
er_2.entity.key.CopyFrom(key_pb2)
conn = self._makeOne()
URI = '/'.join([
conn.API_BASE_URL,
conn.api_base_url,
'datastore',
conn.API_VERSION,
'datasets',
Expand Down Expand Up @@ -432,7 +437,7 @@ def test_lookup_multiple_keys_w_deferred(self):
rsp_pb.deferred.add().CopyFrom(key_pb2)
conn = self._makeOne()
URI = '/'.join([
conn.API_BASE_URL,
conn.api_base_url,
'datastore',
conn.API_VERSION,
'datasets',
Expand Down Expand Up @@ -473,7 +478,7 @@ def test_run_query_w_eventual_no_transaction(self):
rsp_pb.batch.entity_result_type = datastore_pb.EntityResult.FULL
conn = self._makeOne()
URI = '/'.join([
conn.API_BASE_URL,
conn.api_base_url,
'datastore',
conn.API_VERSION,
'datasets',
Expand Down Expand Up @@ -513,7 +518,7 @@ def test_run_query_wo_eventual_w_transaction(self):
rsp_pb.batch.entity_result_type = datastore_pb.EntityResult.FULL
conn = self._makeOne()
URI = '/'.join([
conn.API_BASE_URL,
conn.api_base_url,
'datastore',
conn.API_VERSION,
'datasets',
Expand Down Expand Up @@ -569,7 +574,7 @@ def test_run_query_wo_namespace_empty_result(self):
rsp_pb.batch.entity_result_type = datastore_pb.EntityResult.FULL
conn = self._makeOne()
URI = '/'.join([
conn.API_BASE_URL,
conn.api_base_url,
'datastore',
conn.API_VERSION,
'datasets',
Expand Down Expand Up @@ -603,7 +608,7 @@ def test_run_query_w_namespace_nonempty_result(self):
rsp_pb.batch.more_results = 3 # NO_MORE_RESULTS
conn = self._makeOne()
URI = '/'.join([
conn.API_BASE_URL,
conn.api_base_url,
'datastore',
conn.API_VERSION,
'datasets',
Expand All @@ -630,7 +635,7 @@ def test_begin_transaction_default_serialize(self):
rsp_pb.transaction = TRANSACTION
conn = self._makeOne()
URI = '/'.join([
conn.API_BASE_URL,
conn.api_base_url,
'datastore',
conn.API_VERSION,
'datasets',
Expand All @@ -655,7 +660,7 @@ def test_begin_transaction_explicit_serialize(self):
rsp_pb.transaction = TRANSACTION
conn = self._makeOne()
URI = '/'.join([
conn.API_BASE_URL,
conn.api_base_url,
'datastore',
conn.API_VERSION,
'datasets',
Expand Down Expand Up @@ -685,7 +690,7 @@ def test_commit_wo_transaction(self):
prop.value.string_value = u'Foo'
conn = self._makeOne()
URI = '/'.join([
conn.API_BASE_URL,
conn.api_base_url,
'datastore',
conn.API_VERSION,
'datasets',
Expand Down Expand Up @@ -719,7 +724,7 @@ def test_commit_w_transaction(self):
prop.value.string_value = u'Foo'
conn = self._makeOne()
URI = '/'.join([
conn.API_BASE_URL,
conn.api_base_url,
'datastore',
conn.API_VERSION,
'datasets',
Expand Down Expand Up @@ -747,7 +752,7 @@ def test_rollback_ok(self):
rsp_pb = datastore_pb.RollbackResponse()
conn = self._makeOne()
URI = '/'.join([
conn.API_BASE_URL,
conn.api_base_url,
'datastore',
conn.API_VERSION,
'datasets',
Expand All @@ -770,7 +775,7 @@ def test_allocate_ids_empty(self):
rsp_pb = datastore_pb.AllocateIdsResponse()
conn = self._makeOne()
URI = '/'.join([
conn.API_BASE_URL,
conn.api_base_url,
'datastore',
conn.API_VERSION,
'datasets',
Expand Down Expand Up @@ -803,7 +808,7 @@ def test_allocate_ids_non_empty(self):
rsp_pb.key.add().CopyFrom(after_key_pbs[1])
conn = self._makeOne()
URI = '/'.join([
conn.API_BASE_URL,
conn.api_base_url,
'datastore',
conn.API_VERSION,
'datasets',
Expand Down
Loading

0 comments on commit b9aaf10

Please sign in to comment.