Skip to content

Commit

Permalink
Merge pull request googleapis#140 from jgeewax/some-of-koss-document
Browse files Browse the repository at this point in the history
Adding emulator host and _api property to Firestore client.
  • Loading branch information
mckoss authored Dec 9, 2016
2 parents 94fb5d9 + 738ffd1 commit 6a2d517
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 10 deletions.
14 changes: 7 additions & 7 deletions firestore/google/cloud/firestore/_values.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,14 @@ def encode_value(val):

if isinstance(val, dict):
try:
return Value(entity_value=Entity(properties=_encode_dict(val)))
return Value(entity_value=Entity(properties=encode_dict(val)))
except DepthError:
raise ValueError(
'Dictionary is deeper than %d levels or contains a cycle: %r' %
(MAX_DEPTH, val))

raise TypeError('Cannot convert type (%s) to a Firestore Value.' %
type(val))
(type(val),))


def decode_value(val):
Expand Down Expand Up @@ -131,9 +131,9 @@ def decode_value(val):

if value_type == 'entity_value':
return document.Document(None, None,
_decode_dict(val.entity_value.properties))
decode_dict(val.entity_value.properties))

raise ValueError('Unknown Value type: %r' % value_type)
raise ValueError('Unknown Value type: %r' % (value_type,))


def _is_ascii(text):
Expand All @@ -154,7 +154,7 @@ class DepthError(ValueError):
pass


def _encode_dict(dict_input, depth=1):
def encode_dict(dict_input, depth=1):
"""Encode a dictionary of Python native values, into a dictionary of
Firestore protobuf ``Values``.
Expand All @@ -176,13 +176,13 @@ def _encode_dict(dict_input, depth=1):
for name, value in six.iteritems(dict_input):
if isinstance(value, dict):
result[name] = Value(
entity_value=Entity(properties=_encode_dict(value, depth + 1)))
entity_value=Entity(properties=encode_dict(value, depth + 1)))
else:
result[name] = encode_value(value)
return result


def _decode_dict(dict_input):
def decode_dict(dict_input):
"""Decode a dictionary of Firestore protobuf Values, into a dictionary of
Python native values.
Expand Down
39 changes: 38 additions & 1 deletion firestore/google/cloud/firestore/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,16 @@

"""Firestore database SDK Client."""

import grpc

from google.cloud._helpers import make_secure_channel
from google.cloud._http import DEFAULT_USER_AGENT
from google.cloud.client import Client as _BaseClient
from google.cloud.client import _ClientProjectMixin
from google.cloud.credentials import get_credentials

from google.cloud.gapic.firestore.v1alpha1 import datastore_api


ALL_SCOPES = ('https://www.googleapis.com/auth/cloud-platform',
'https://www.googleapis.com/auth/datastore')
Expand All @@ -35,9 +41,13 @@ class Client(_BaseClient, _ClientProjectMixin):
:param credentials: (optional) The OAuth2 Credentials to use for this
client. If not provided, defaults to the Google
Application Default Credentials.
:type emulator_host: str
:param emulator_host: (optional) Host name of local Firestore emulator
(e.g., 'localhost:12345').
"""

def __init__(self, project=None, credentials=None):
def __init__(self, project=None, credentials=None, emulator_host=None):
if credentials is None:
credentials = get_credentials()

Expand All @@ -48,3 +58,30 @@ def __init__(self, project=None, credentials=None):

_ClientProjectMixin.__init__(self, project=project)
_BaseClient.__init__(self, credentials=credentials)
self.database_id = None
self._api = _make_firestore_api(self._connection, emulator_host)


def _make_firestore_api(connection, emulator_host):
"""Create a Firestore gRPC helper library.
:type connection: :class:`~google.cloud._http.Connection`
:param connection: Connection to Google Cloud Platform.
:type emulator_host: str
:param emulator_host: (optional) Host name of local Firestore emulator
(e.g., 'localhost:12345').
:rtype:
:class:`google.cloud.gapic.firestore.v1alpha1.datastore_api.DatastoreApi`
:returns: A gRPC api helper class.
"""
if emulator_host is not None:
channel = grpc.insecure_channel(emulator_host)
else:
channel = make_secure_channel(
connection.credentials,
DEFAULT_USER_AGENT,
datastore_api.DatastoreApi.SERVICE_ADDRESS)

return datastore_api.DatastoreApi(channel=channel)
1 change: 1 addition & 0 deletions firestore/google/cloud/firestore/path.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ def child(self, *parts):
"""
return Path(*(self._parts + parts))

@property
def parent(self):
"""Create a Path to the parent Document or Collection.
Expand Down
5 changes: 5 additions & 0 deletions firestore/unit_tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ def test_constructor(self):
client = self._make_one('my-project-id')
self.assertEqual(client.project, 'my-project-id')

def test_constructor_emulator(self):
client = self._make_one('my-project-id',
emulator_host='localhost:12345')
self.assertEqual(client.project, 'my-project-id')

def test_empty_constructor(self):
import mock

Expand Down
4 changes: 2 additions & 2 deletions firestore/unit_tests/test_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ def test_child(self):
def test_parent(self):
path1 = self._make_one('my-collection')
path2 = self._make_one('my-collection', 'my-document')
self.assertEqual(path2.parent(), path1)
self.assertNotEqual(path1.parent(), path2)
self.assertEqual(path2.parent, path1)
self.assertNotEqual(path1.parent, path2)

def test_kind(self):
path1 = self._make_one('my-collection')
Expand Down

0 comments on commit 6a2d517

Please sign in to comment.