-
Notifications
You must be signed in to change notification settings - Fork 336
feat(firestore): Expose Async Firestore Client. #621
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 1 commit
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
78606e3
feat(firestore): Expose Async Firestore Client.
jkyle109 fe565e8
fix: Added type hints and defintion wording changes
jkyle109 a1c7838
fix: removed future annotations until Python 3.6 is depreciated.
jkyle109 bad8e6d
fix: added missed type and clarifying comment for Python 3.6 type hin…
jkyle109 0ca6bc7
fix: lint
jkyle109 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
# Copyright 2017 Google Inc. | ||
# | ||
# 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. | ||
|
||
"""Cloud Firestore Async module. | ||
|
||
This module contains utilities for accessing the Google Cloud Firestore databases associated with | ||
jkyle109 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Firebase apps. This requires the ``google-cloud-firestore`` Python module. | ||
""" | ||
|
||
try: | ||
from google.cloud import firestore # pylint: disable=import-error,no-name-in-module | ||
existing = globals().keys() | ||
for key, value in firestore.__dict__.items(): | ||
if not key.startswith('_') and key not in existing: | ||
globals()[key] = value | ||
except ImportError: | ||
raise ImportError('Failed to import the Cloud Firestore library for Python. Make sure ' | ||
'to install the "google-cloud-firestore" module.') | ||
|
||
from firebase_admin import _utils | ||
|
||
|
||
_FIRESTORE_ASYNC_ATTRIBUTE = '_firestore_async' | ||
|
||
|
||
def client(app=None): | ||
jkyle109 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"""Returns a client that can be used to interact with Google Cloud Firestore. | ||
jkyle109 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Args: | ||
app: An App instance (optional). | ||
|
||
Returns: | ||
google.cloud.firestore.Firestore_Async: A `Firestore Async Client`_. | ||
jkyle109 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Raises: | ||
ValueError: If a project ID is not specified either via options, credentials or | ||
environment variables, or if the specified project ID is not a valid string. | ||
|
||
.. _Firestore Async Client: https://googleapis.dev/python/firestore/latest/client.html | ||
""" | ||
fs_client = _utils.get_app_service( | ||
app, _FIRESTORE_ASYNC_ATTRIBUTE, _FirestoreAsyncClient.from_app) | ||
return fs_client.get() | ||
|
||
|
||
class _FirestoreAsyncClient: | ||
"""Holds a Google Cloud Firestore Async Client instance.""" | ||
|
||
def __init__(self, credentials, project): | ||
self._client = firestore.AsyncClient(credentials=credentials, project=project) | ||
|
||
def get(self): | ||
return self._client | ||
|
||
@classmethod | ||
def from_app(cls, app): | ||
"""Creates a new _FirestoreAsyncClient for the specified app.""" | ||
credentials = app.credential.get_credential() | ||
project = app.project_id | ||
if not project: | ||
raise ValueError( | ||
'Project ID is required to access Firestore. Either set the projectId option, ' | ||
'or use service account credentials. Alternatively, set the GOOGLE_CLOUD_PROJECT ' | ||
'environment variable.') | ||
return _FirestoreAsyncClient(credentials, project) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
# Copyright 2017 Google Inc. | ||
jkyle109 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
# | ||
# 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. | ||
|
||
"""Tests for firebase_admin.firestore_async.""" | ||
|
||
import platform | ||
|
||
import pytest | ||
|
||
import firebase_admin | ||
from firebase_admin import credentials | ||
try: | ||
from firebase_admin import firestore_async | ||
except ImportError: | ||
pass | ||
from tests import testutils | ||
|
||
|
||
@pytest.mark.skipif( | ||
platform.python_implementation() == 'PyPy', | ||
reason='Firestore is not supported on PyPy') | ||
class TestFirestoreAsync: | ||
"""Test class Firestore Async APIs.""" | ||
|
||
def teardown_method(self, method): | ||
del method | ||
testutils.cleanup_apps() | ||
|
||
def test_no_project_id(self): | ||
def evaluate(): | ||
firebase_admin.initialize_app(testutils.MockCredential()) | ||
with pytest.raises(ValueError): | ||
firestore_async.client() | ||
testutils.run_without_project_id(evaluate) | ||
|
||
def test_project_id(self): | ||
cred = credentials.Certificate(testutils.resource_filename('service_account.json')) | ||
firebase_admin.initialize_app(cred, {'projectId': 'explicit-project-id'}) | ||
client = firestore_async.client() | ||
assert client is not None | ||
assert client.project == 'explicit-project-id' | ||
|
||
def test_project_id_with_explicit_app(self): | ||
cred = credentials.Certificate(testutils.resource_filename('service_account.json')) | ||
app = firebase_admin.initialize_app(cred, {'projectId': 'explicit-project-id'}) | ||
client = firestore_async.client(app=app) | ||
assert client is not None | ||
assert client.project == 'explicit-project-id' | ||
|
||
def test_service_account(self): | ||
cred = credentials.Certificate(testutils.resource_filename('service_account.json')) | ||
firebase_admin.initialize_app(cred) | ||
client = firestore_async.client() | ||
assert client is not None | ||
assert client.project == 'mock-project-id' | ||
|
||
def test_service_account_with_explicit_app(self): | ||
cred = credentials.Certificate(testutils.resource_filename('service_account.json')) | ||
app = firebase_admin.initialize_app(cred) | ||
client = firestore_async.client(app=app) | ||
assert client is not None | ||
assert client.project == 'mock-project-id' | ||
|
||
def test_geo_point(self): | ||
geo_point = firestore_async.GeoPoint(10, 20) # pylint: disable=no-member | ||
assert geo_point.latitude == 10 | ||
assert geo_point.longitude == 20 | ||
|
||
def test_server_timestamp(self): | ||
assert firestore_async.SERVER_TIMESTAMP is not None # pylint: disable=no-member |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.