Skip to content

Commit

Permalink
Merge pull request googleapis#141 from jgeewax/some-of-koss-document-2
Browse files Browse the repository at this point in the history
Adding a shell "CollectionRef" class (some-of-koss-document-2).
  • Loading branch information
mckoss authored Dec 14, 2016
2 parents 6a2d517 + dd106d5 commit a0c9f7f
Show file tree
Hide file tree
Showing 11 changed files with 213 additions and 28 deletions.
5 changes: 5 additions & 0 deletions docs/firestore-collection.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Firestore Collections
=====================
.. autoclass:: google.cloud.firestore.CollectionRef
:members:
:show-inheritance:
5 changes: 5 additions & 0 deletions docs/firestore-document.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Firestore Documents
===================
.. autoclass:: google.cloud.firestore.Document
:members:
:show-inheritance:
2 changes: 2 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@

firestore
firestore-client
firestore-collection
firestore-document
firestore-path

.. toctree::
Expand Down
8 changes: 7 additions & 1 deletion firestore/google/cloud/firestore/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,14 @@
"""Firestore database API public classes."""

from google.cloud.firestore.client import Client
from google.cloud.firestore.collection import CollectionRef
from google.cloud.firestore.document import Document
from google.cloud.firestore.path import Path


__all__ = ['Client', 'Path', 'Document']
__all__ = [
'Client',
'Path',
'Document',
'CollectionRef',
]
8 changes: 3 additions & 5 deletions firestore/google/cloud/firestore/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import grpc

import google.auth
from google.cloud._helpers import make_secure_channel
from google.cloud._http import DEFAULT_USER_AGENT
from google.cloud.client import Client as _BaseClient
Expand Down Expand Up @@ -51,11 +52,8 @@ def __init__(self, project=None, credentials=None, emulator_host=None):
if credentials is None:
credentials = get_credentials()

try:
credentials = credentials.create_scoped(ALL_SCOPES)
except AttributeError:
pass

credentials = google.auth.credentials.with_scopes_if_required(
credentials, ALL_SCOPES)
_ClientProjectMixin.__init__(self, project=project)
_BaseClient.__init__(self, credentials=credentials)
self.database_id = None
Expand Down
30 changes: 30 additions & 0 deletions firestore/google/cloud/firestore/collection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright 2016 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Firestore Collection and Query classes."""


class CollectionRef(object):
"""Reference to a collection location in a Firestore database.
:type client: :class:`~google.cloud.firestore.Client`
:param client: Firestore client context.
:type path: :class:`~google.cloud.firestore.Path`
:param path: Path location of this collection.
"""

def __init__(self, client, path):
self._client = client
self._path = path
50 changes: 47 additions & 3 deletions firestore/google/cloud/firestore/document.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,53 @@


class Document(dict):
"""Firestore Document."""
"""Firestore Document.
A ``Document`` is a dictionary-like object containing the properties
of a document stored in the Firestore database.
:type client: :class:`~google.cloud.firestore.Client`
:param client: Firestore client context.
:type path: :class:`~google.cloud.firestore.Path`
:param path: Location ``Document`` is stored.
:type properties: dict
:param properties: A dictionary of values from which
the document is initialized.
:type version: int
:param version: (optional) The document version number when saved.
"""

def __init__(self, client, path=None, properties=None, version=None):
if properties is None:
properties = {}

def __init__(self, firestore, path, properties):
super(Document, self).__init__(properties)
self._firestore = firestore

if path is not None and not path.is_document:
raise ValueError('Invalid document path: %s' % (path,))

self._client = client
self._path = path
self._version = version

@property
def doc_id(self):
"""The `Document` identifier unique in its collection.
:rtype: str or None
:returns: The last component of a path for a `Document` (or None if the
Document has not been saved to the Firestore database.).
"""
return self._path.id

@property
def version(self):
"""The version number of the Document when last saved.
:rtype: int or None
:returns: The document's version number.
"""
return self._version
26 changes: 8 additions & 18 deletions firestore/unit_tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@
import unittest


def _make_credentials():
import google.auth.credentials
import mock

return mock.Mock(spec=google.auth.credentials.Credentials)


class TestClient(unittest.TestCase):

@staticmethod
Expand Down Expand Up @@ -46,23 +53,6 @@ def test_empty_constructor(self):
self.assertEqual(client.project, project)

def test_credentialed_constructor(self):
from google.cloud.firestore.client import ALL_SCOPES

creds = MockCredentials()
client = self._make_one('my-project-id', credentials=creds)
self.assertIs(client._connection.credentials, creds)
self.assertEqual(creds.scopes, ALL_SCOPES)

def test_credentialed_no_scopes_constructor(self):
creds = object()
creds = _make_credentials()
client = self._make_one('my-project-id', credentials=creds)
self.assertIs(client._connection.credentials, creds)


class MockCredentials(object):
def __init__(self):
self.scopes = None

def create_scoped(self, scopes):
self.scopes = scopes
return self
36 changes: 36 additions & 0 deletions firestore/unit_tests/test_collection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Copyright 2016 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import unittest


class TestCollectionRef(unittest.TestCase):

@staticmethod
def _get_target_class():
from google.cloud.firestore.collection import CollectionRef

return CollectionRef

def _make_one(self, *args, **kwargs):
return self._get_target_class()(*args, **kwargs)

def test_constructor(self):
from google.cloud.firestore.path import Path

client = object()
path = Path('my-collection')
col_ref = self._make_one(client, path)
self.assertIs(col_ref._client, client)
self.assertEqual(col_ref._path, path)
68 changes: 68 additions & 0 deletions firestore/unit_tests/test_document.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Copyright 2016 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www125.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import unittest


class TestDocument(unittest.TestCase):

@staticmethod
def _get_target_class():
from google.cloud.firestore.document import Document

return Document

def _make_one(self, client, path=None, properties=None, *args, **kwargs):
from google.cloud.firestore.path import Path

if path is None:
path = Path('my-collection', 'my-document')

return self._get_target_class()(client, path, properties,
*args, **kwargs)

def test_constructor(self):
from google.cloud.firestore.path import Path

client = object()
properties = {'hi': 'mom'}
path = Path('my-collection', 'my-document', 'sub-collection', 1234)
version = 498
doc = self._make_one(client, path, properties, version=version)
self.assertIs(doc._client, client)
self.assertIs(doc._path, path)
self.assertEqual(doc._version, version)
self.assertEqual(dict(doc), properties)

def test_constructor_path_non_document(self):
from google.cloud.firestore.path import Path

client = object()
collection_path = Path('my-collection')
with self.assertRaisesRegexp(ValueError, 'Invalid'):
self._make_one(client, collection_path)

def test_doc_id(self):
from google.cloud.firestore.path import Path

client = object()
doc_id = 'my-document'
path = Path('my-collection', doc_id)
doc = self._make_one(client, path)
self.assertEqual(doc.doc_id, doc_id)

def test_version(self):
client = object()
doc = self._make_one(client, version=123)
self.assertEqual(doc.version, 123)
3 changes: 2 additions & 1 deletion scripts/verify_included_modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@
'google.cloud.dns',
'google.cloud.error_reporting',
'google.cloud.firestore.client',
'google.cloud.firestore.path',
'google.cloud.firestore.collection',
'google.cloud.firestore.document',
'google.cloud.firestore.path',
'google.cloud.language',
'google.cloud.logging',
'google.cloud.logging.handlers',
Expand Down

0 comments on commit a0c9f7f

Please sign in to comment.