Skip to content

Commit cd4e7d6

Browse files
authored
Shallow reads support in database API (firebase#109)
* Shallow reads support in database API * Updated docstring
1 parent d2b3c94 commit cd4e7d6

File tree

3 files changed

+30
-2
lines changed

3 files changed

+30
-2
lines changed

firebase_admin/db.py

+9-2
Original file line numberDiff line numberDiff line change
@@ -125,26 +125,33 @@ def child(self, path):
125125
full_path = self._pathurl + '/' + path
126126
return Reference(client=self._client, path=full_path)
127127

128-
def get(self, etag=False):
128+
def get(self, etag=False, shallow=False):
129129
"""Returns the value, and optionally the ETag, at the current location of the database.
130130
131131
Args:
132132
etag: A boolean indicating whether the Etag value should be returned or not (optional).
133+
shallow: A boolean indicating whether to execute a shallow read (optional). Shallow
134+
reads do not retrieve the child nodes of the current database location. Cannot be
135+
set to True if ``etag`` is also set to True.
133136
134137
Returns:
135138
object: If etag is False returns the decoded JSON value of the current database location.
136139
If etag is True, returns a 2-tuple consisting of the decoded JSON value and the Etag
137140
associated with the current database location.
138141
139142
Raises:
143+
ValueError: If both ``etag`` and ``shallow`` are set to True.
140144
ApiCallError: If an error occurs while communicating with the remote database server.
141145
"""
142146
if etag:
147+
if shallow:
148+
raise ValueError('etag and shallow cannot both be set to True.')
143149
headers, data = self._client.headers_and_body(
144150
'get', self._add_suffix(), headers={'X-Firebase-ETag' : 'true'})
145151
return data, headers.get('ETag')
146152
else:
147-
return self._client.body('get', self._add_suffix())
153+
params = 'shallow=true' if shallow else None
154+
return self._client.body('get', self._add_suffix(), params=params)
148155

149156
def get_if_changed(self, etag):
150157
"""Gets data in this location only if the specified ETag does not match.

integration/test_db.py

+5
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ def test_get_value_and_etag(self, testref, testdata):
8989
assert testdata == value
9090
assert isinstance(etag, six.string_types)
9191

92+
def test_get_shallow(self, testref):
93+
value = testref.get(shallow=True)
94+
assert isinstance(value, dict)
95+
assert value == {'dinosaurs': True, 'scores': True}
96+
9297
def test_get_if_changed(self, testref, testdata):
9398
success, data, etag = testref.get_if_changed('wrong_etag')
9499
assert success is True

tests/test_db.py

+16
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,22 @@ def test_get_with_etag(self, data):
155155
assert recorder[0].headers['User-Agent'] == db._USER_AGENT
156156
assert recorder[0].headers['X-Firebase-ETag'] == 'true'
157157

158+
@pytest.mark.parametrize('data', valid_values)
159+
def test_get_shallow(self, data):
160+
ref = db.reference('/test')
161+
recorder = self.instrument(ref, json.dumps(data))
162+
assert ref.get(shallow=True) == data
163+
assert len(recorder) == 1
164+
assert recorder[0].method == 'GET'
165+
assert recorder[0].url == 'https://test.firebaseio.com/test.json?shallow=true'
166+
assert recorder[0].headers['Authorization'] == 'Bearer mock-token'
167+
assert recorder[0].headers['User-Agent'] == db._USER_AGENT
168+
169+
def test_get_with_etag_and_shallow(self):
170+
ref = db.reference('/test')
171+
with pytest.raises(ValueError):
172+
ref.get(etag=True, shallow=True)
173+
158174
@pytest.mark.parametrize('data', valid_values)
159175
def test_get_if_changed(self, data):
160176
ref = db.reference('/test')

0 commit comments

Comments
 (0)