Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/google/cloud/firestore_v1/collection.py: 58%

36 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-12-09 06:27 +0000

1# Copyright 2017 Google LLC All rights reserved. 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"); 

4# you may not use this file except in compliance with the License. 

5# You may obtain a copy of the License at 

6# 

7# http://www.apache.org/licenses/LICENSE-2.0 

8# 

9# Unless required by applicable law or agreed to in writing, software 

10# distributed under the License is distributed on an "AS IS" BASIS, 

11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

12# See the License for the specific language governing permissions and 

13# limitations under the License. 

14 

15"""Classes for representing collections for the Google Cloud Firestore API.""" 

16 

17from google.api_core import gapic_v1 

18from google.api_core import retry as retries 

19 

20from google.cloud.firestore_v1.base_collection import ( 

21 BaseCollectionReference, 

22 _item_to_document_ref, 

23) 

24from google.cloud.firestore_v1 import query as query_mod 

25from google.cloud.firestore_v1 import aggregation 

26from google.cloud.firestore_v1.watch import Watch 

27from google.cloud.firestore_v1 import document 

28from typing import Any, Callable, Generator, Tuple, Union 

29 

30# Types needed only for Type Hints 

31from google.cloud.firestore_v1.transaction import Transaction 

32 

33 

34class CollectionReference(BaseCollectionReference[query_mod.Query]): 

35 """A reference to a collection in a Firestore database. 

36 

37 The collection may already exist or this class can facilitate creation 

38 of documents within the collection. 

39 

40 Args: 

41 path (Tuple[str, ...]): The components in the collection path. 

42 This is a series of strings representing each collection and 

43 sub-collection ID, as well as the document IDs for any documents 

44 that contain a sub-collection. 

45 kwargs (dict): The keyword arguments for the constructor. The only 

46 supported keyword is ``client`` and it must be a 

47 :class:`~google.cloud.firestore_v1.client.Client` if provided. It 

48 represents the client that created this collection reference. 

49 

50 Raises: 

51 ValueError: if 

52 

53 * the ``path`` is empty 

54 * there are an even number of elements 

55 * a collection ID in ``path`` is not a string 

56 * a document ID in ``path`` is not a string 

57 TypeError: If a keyword other than ``client`` is used. 

58 """ 

59 

60 def __init__(self, *path, **kwargs) -> None: 

61 super(CollectionReference, self).__init__(*path, **kwargs) 

62 

63 def _query(self) -> query_mod.Query: 

64 """Query factory. 

65 

66 Returns: 

67 :class:`~google.cloud.firestore_v1.query.Query` 

68 """ 

69 return query_mod.Query(self) 

70 

71 def _aggregation_query(self) -> aggregation.AggregationQuery: 

72 """AggregationQuery factory. 

73 

74 Returns: 

75 :class:`~google.cloud.firestore_v1.aggregation_query.AggregationQuery` 

76 """ 

77 return aggregation.AggregationQuery(self._query()) 

78 

79 def add( 

80 self, 

81 document_data: dict, 

82 document_id: Union[str, None] = None, 

83 retry: retries.Retry = gapic_v1.method.DEFAULT, 

84 timeout: Union[float, None] = None, 

85 ) -> Tuple[Any, Any]: 

86 """Create a document in the Firestore database with the provided data. 

87 

88 Args: 

89 document_data (dict): Property names and values to use for 

90 creating the document. 

91 document_id (Optional[str]): The document identifier within the 

92 current collection. If not provided, an ID will be 

93 automatically assigned by the server (the assigned ID will be 

94 a random 20 character string composed of digits, 

95 uppercase and lowercase letters). 

96 retry (google.api_core.retry.Retry): Designation of what errors, if any, 

97 should be retried. Defaults to a system-specified policy. 

98 timeout (float): The timeout for this request. Defaults to a 

99 system-specified value. 

100 

101 Returns: 

102 Tuple[:class:`google.protobuf.timestamp_pb2.Timestamp`, \ 

103 :class:`~google.cloud.firestore_v1.document.DocumentReference`]: 

104 Pair of 

105 

106 * The ``update_time`` when the document was created/overwritten. 

107 * A document reference for the created document. 

108 

109 Raises: 

110 :class:`google.cloud.exceptions.Conflict`: 

111 If ``document_id`` is provided and the document already exists. 

112 """ 

113 document_ref, kwargs = self._prep_add( 

114 document_data, 

115 document_id, 

116 retry, 

117 timeout, 

118 ) 

119 write_result = document_ref.create(document_data, **kwargs) 

120 return write_result.update_time, document_ref 

121 

122 def list_documents( 

123 self, 

124 page_size: Union[int, None] = None, 

125 retry: retries.Retry = gapic_v1.method.DEFAULT, 

126 timeout: Union[float, None] = None, 

127 ) -> Generator[Any, Any, None]: 

128 """List all subdocuments of the current collection. 

129 

130 Args: 

131 page_size (Optional[int]]): The maximum number of documents 

132 in each page of results from this request. Non-positive values 

133 are ignored. Defaults to a sensible value set by the API. 

134 retry (google.api_core.retry.Retry): Designation of what errors, if any, 

135 should be retried. Defaults to a system-specified policy. 

136 timeout (float): The timeout for this request. Defaults to a 

137 system-specified value. 

138 

139 Returns: 

140 Sequence[:class:`~google.cloud.firestore_v1.collection.DocumentReference`]: 

141 iterator of subdocuments of the current collection. If the 

142 collection does not exist at the time of `snapshot`, the 

143 iterator will be empty 

144 """ 

145 request, kwargs = self._prep_list_documents(page_size, retry, timeout) 

146 

147 iterator = self._client._firestore_api.list_documents( 

148 request=request, 

149 metadata=self._client._rpc_metadata, 

150 **kwargs, 

151 ) 

152 return (_item_to_document_ref(self, i) for i in iterator) 

153 

154 def _chunkify(self, chunk_size: int): 

155 return self._query()._chunkify(chunk_size) 

156 

157 def get( 

158 self, 

159 transaction: Union[Transaction, None] = None, 

160 retry: retries.Retry = gapic_v1.method.DEFAULT, 

161 timeout: Union[float, None] = None, 

162 ) -> list: 

163 """Read the documents in this collection. 

164 

165 This sends a ``RunQuery`` RPC and returns a list of documents 

166 returned in the stream of ``RunQueryResponse`` messages. 

167 

168 Args: 

169 transaction 

170 (Optional[:class:`~google.cloud.firestore_v1.transaction.Transaction`]): 

171 An existing transaction that this query will run in. 

172 retry (google.api_core.retry.Retry): Designation of what errors, if any, 

173 should be retried. Defaults to a system-specified policy. 

174 timeout (float): The timeout for this request. Defaults to a 

175 system-specified value. 

176 

177 If a ``transaction`` is used and it already has write operations 

178 added, this method cannot be used (i.e. read-after-write is not 

179 allowed). 

180 

181 Returns: 

182 list: The documents in this collection that match the query. 

183 """ 

184 query, kwargs = self._prep_get_or_stream(retry, timeout) 

185 

186 return query.get(transaction=transaction, **kwargs) 

187 

188 def stream( 

189 self, 

190 transaction: Union[Transaction, None] = None, 

191 retry: retries.Retry = gapic_v1.method.DEFAULT, 

192 timeout: Union[float, None] = None, 

193 ) -> Generator[document.DocumentSnapshot, Any, None]: 

194 """Read the documents in this collection. 

195 

196 This sends a ``RunQuery`` RPC and then returns an iterator which 

197 consumes each document returned in the stream of ``RunQueryResponse`` 

198 messages. 

199 

200 .. note:: 

201 

202 The underlying stream of responses will time out after 

203 the ``max_rpc_timeout_millis`` value set in the GAPIC 

204 client configuration for the ``RunQuery`` API. Snapshots 

205 not consumed from the iterator before that point will be lost. 

206 

207 If a ``transaction`` is used and it already has write operations 

208 added, this method cannot be used (i.e. read-after-write is not 

209 allowed). 

210 

211 Args: 

212 transaction (Optional[:class:`~google.cloud.firestore_v1.transaction.\ 

213 Transaction`]): 

214 An existing transaction that the query will run in. 

215 retry (google.api_core.retry.Retry): Designation of what errors, if any, 

216 should be retried. Defaults to a system-specified policy. 

217 timeout (float): The timeout for this request. Defaults to a 

218 system-specified value. 

219 

220 Yields: 

221 :class:`~google.cloud.firestore_v1.document.DocumentSnapshot`: 

222 The next document that fulfills the query. 

223 """ 

224 query, kwargs = self._prep_get_or_stream(retry, timeout) 

225 

226 return query.stream(transaction=transaction, **kwargs) 

227 

228 def on_snapshot(self, callback: Callable) -> Watch: 

229 """Monitor the documents in this collection. 

230 

231 This starts a watch on this collection using a background thread. The 

232 provided callback is run on the snapshot of the documents. 

233 

234 Args: 

235 callback (Callable[[:class:`~google.cloud.firestore.collection.CollectionSnapshot`], NoneType]): 

236 a callback to run when a change occurs. 

237 

238 Example: 

239 from google.cloud import firestore_v1 

240 

241 db = firestore_v1.Client() 

242 collection_ref = db.collection(u'users') 

243 

244 def on_snapshot(collection_snapshot, changes, read_time): 

245 for doc in collection_snapshot.documents: 

246 print(u'{} => {}'.format(doc.id, doc.to_dict())) 

247 

248 # Watch this collection 

249 collection_watch = collection_ref.on_snapshot(on_snapshot) 

250 

251 # Terminate this watch 

252 collection_watch.unsubscribe() 

253 """ 

254 query = self._query() 

255 return Watch.for_query(query, callback, document.DocumentSnapshot)