Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/google/cloud/firestore_v1/services/firestore/transports/grpc.py: 45%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

173 statements  

1# -*- coding: utf-8 -*- 

2# Copyright 2025 Google LLC 

3# 

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

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

6# You may obtain a copy of the License at 

7# 

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

9# 

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

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

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

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

14# limitations under the License. 

15# 

16import json 

17import logging as std_logging 

18import pickle 

19import warnings 

20from typing import Callable, Dict, Optional, Sequence, Tuple, Union 

21 

22from google.api_core import grpc_helpers 

23from google.api_core import gapic_v1 

24import google.auth # type: ignore 

25from google.auth import credentials as ga_credentials # type: ignore 

26from google.auth.transport.grpc import SslCredentials # type: ignore 

27from google.protobuf.json_format import MessageToJson 

28import google.protobuf.message 

29 

30import grpc # type: ignore 

31import proto # type: ignore 

32 

33from google.cloud.firestore_v1.types import document 

34from google.cloud.firestore_v1.types import document as gf_document 

35from google.cloud.firestore_v1.types import firestore 

36from google.cloud.location import locations_pb2 # type: ignore 

37from google.longrunning import operations_pb2 # type: ignore 

38from google.protobuf import empty_pb2 # type: ignore 

39from .base import FirestoreTransport, DEFAULT_CLIENT_INFO 

40 

41try: 

42 from google.api_core import client_logging # type: ignore 

43 

44 CLIENT_LOGGING_SUPPORTED = True # pragma: NO COVER 

45except ImportError: # pragma: NO COVER 

46 CLIENT_LOGGING_SUPPORTED = False 

47 

48_LOGGER = std_logging.getLogger(__name__) 

49 

50 

51class _LoggingClientInterceptor(grpc.UnaryUnaryClientInterceptor): # pragma: NO COVER 

52 def intercept_unary_unary(self, continuation, client_call_details, request): 

53 logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( 

54 std_logging.DEBUG 

55 ) 

56 if logging_enabled: # pragma: NO COVER 

57 request_metadata = client_call_details.metadata 

58 if isinstance(request, proto.Message): 

59 request_payload = type(request).to_json(request) 

60 elif isinstance(request, google.protobuf.message.Message): 

61 request_payload = MessageToJson(request) 

62 else: 

63 request_payload = f"{type(request).__name__}: {pickle.dumps(request)}" 

64 

65 request_metadata = { 

66 key: value.decode("utf-8") if isinstance(value, bytes) else value 

67 for key, value in request_metadata 

68 } 

69 grpc_request = { 

70 "payload": request_payload, 

71 "requestMethod": "grpc", 

72 "metadata": dict(request_metadata), 

73 } 

74 _LOGGER.debug( 

75 f"Sending request for {client_call_details.method}", 

76 extra={ 

77 "serviceName": "google.firestore.v1.Firestore", 

78 "rpcName": str(client_call_details.method), 

79 "request": grpc_request, 

80 "metadata": grpc_request["metadata"], 

81 }, 

82 ) 

83 response = continuation(client_call_details, request) 

84 if logging_enabled: # pragma: NO COVER 

85 response_metadata = response.trailing_metadata() 

86 # Convert gRPC metadata `<class 'grpc.aio._metadata.Metadata'>` to list of tuples 

87 metadata = ( 

88 dict([(k, str(v)) for k, v in response_metadata]) 

89 if response_metadata 

90 else None 

91 ) 

92 result = response.result() 

93 if isinstance(result, proto.Message): 

94 response_payload = type(result).to_json(result) 

95 elif isinstance(result, google.protobuf.message.Message): 

96 response_payload = MessageToJson(result) 

97 else: 

98 response_payload = f"{type(result).__name__}: {pickle.dumps(result)}" 

99 grpc_response = { 

100 "payload": response_payload, 

101 "metadata": metadata, 

102 "status": "OK", 

103 } 

104 _LOGGER.debug( 

105 f"Received response for {client_call_details.method}.", 

106 extra={ 

107 "serviceName": "google.firestore.v1.Firestore", 

108 "rpcName": client_call_details.method, 

109 "response": grpc_response, 

110 "metadata": grpc_response["metadata"], 

111 }, 

112 ) 

113 return response 

114 

115 

116class FirestoreGrpcTransport(FirestoreTransport): 

117 """gRPC backend transport for Firestore. 

118 

119 The Cloud Firestore service. 

120 

121 Cloud Firestore is a fast, fully managed, serverless, 

122 cloud-native NoSQL document database that simplifies storing, 

123 syncing, and querying data for your mobile, web, and IoT apps at 

124 global scale. Its client libraries provide live synchronization 

125 and offline support, while its security features and 

126 integrations with Firebase and Google Cloud Platform accelerate 

127 building truly serverless apps. 

128 

129 This class defines the same methods as the primary client, so the 

130 primary client can load the underlying transport implementation 

131 and call it. 

132 

133 It sends protocol buffers over the wire using gRPC (which is built on 

134 top of HTTP/2); the ``grpcio`` package must be installed. 

135 """ 

136 

137 _stubs: Dict[str, Callable] 

138 

139 def __init__( 

140 self, 

141 *, 

142 host: str = "firestore.googleapis.com", 

143 credentials: Optional[ga_credentials.Credentials] = None, 

144 credentials_file: Optional[str] = None, 

145 scopes: Optional[Sequence[str]] = None, 

146 channel: Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]] = None, 

147 api_mtls_endpoint: Optional[str] = None, 

148 client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, 

149 ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, 

150 client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, 

151 quota_project_id: Optional[str] = None, 

152 client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, 

153 always_use_jwt_access: Optional[bool] = False, 

154 api_audience: Optional[str] = None, 

155 ) -> None: 

156 """Instantiate the transport. 

157 

158 Args: 

159 host (Optional[str]): 

160 The hostname to connect to (default: 'firestore.googleapis.com'). 

161 credentials (Optional[google.auth.credentials.Credentials]): The 

162 authorization credentials to attach to requests. These 

163 credentials identify the application to the service; if none 

164 are specified, the client will attempt to ascertain the 

165 credentials from the environment. 

166 This argument is ignored if a ``channel`` instance is provided. 

167 credentials_file (Optional[str]): Deprecated. A file with credentials that can 

168 be loaded with :func:`google.auth.load_credentials_from_file`. 

169 This argument is ignored if a ``channel`` instance is provided. 

170 This argument will be removed in the next major version of this library. 

171 scopes (Optional(Sequence[str])): A list of scopes. This argument is 

172 ignored if a ``channel`` instance is provided. 

173 channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]): 

174 A ``Channel`` instance through which to make calls, or a Callable 

175 that constructs and returns one. If set to None, ``self.create_channel`` 

176 is used to create the channel. If a Callable is given, it will be called 

177 with the same arguments as used in ``self.create_channel``. 

178 api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. 

179 If provided, it overrides the ``host`` argument and tries to create 

180 a mutual TLS channel with client SSL credentials from 

181 ``client_cert_source`` or application default SSL credentials. 

182 client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): 

183 Deprecated. A callback to provide client SSL certificate bytes and 

184 private key bytes, both in PEM format. It is ignored if 

185 ``api_mtls_endpoint`` is None. 

186 ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials 

187 for the grpc channel. It is ignored if a ``channel`` instance is provided. 

188 client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): 

189 A callback to provide client certificate bytes and private key bytes, 

190 both in PEM format. It is used to configure a mutual TLS channel. It is 

191 ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. 

192 quota_project_id (Optional[str]): An optional project to use for billing 

193 and quota. 

194 client_info (google.api_core.gapic_v1.client_info.ClientInfo): 

195 The client info used to send a user-agent string along with 

196 API requests. If ``None``, then default info will be used. 

197 Generally, you only need to set this if you're developing 

198 your own client library. 

199 always_use_jwt_access (Optional[bool]): Whether self signed JWT should 

200 be used for service account credentials. 

201 

202 Raises: 

203 google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport 

204 creation failed for any reason. 

205 google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` 

206 and ``credentials_file`` are passed. 

207 """ 

208 self._grpc_channel = None 

209 self._ssl_channel_credentials = ssl_channel_credentials 

210 self._stubs: Dict[str, Callable] = {} 

211 

212 if api_mtls_endpoint: 

213 warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) 

214 if client_cert_source: 

215 warnings.warn("client_cert_source is deprecated", DeprecationWarning) 

216 

217 if isinstance(channel, grpc.Channel): 

218 # Ignore credentials if a channel was passed. 

219 credentials = None 

220 self._ignore_credentials = True 

221 # If a channel was explicitly provided, set it. 

222 self._grpc_channel = channel 

223 self._ssl_channel_credentials = None 

224 

225 else: 

226 if api_mtls_endpoint: 

227 host = api_mtls_endpoint 

228 

229 # Create SSL credentials with client_cert_source or application 

230 # default SSL credentials. 

231 if client_cert_source: 

232 cert, key = client_cert_source() 

233 self._ssl_channel_credentials = grpc.ssl_channel_credentials( 

234 certificate_chain=cert, private_key=key 

235 ) 

236 else: 

237 self._ssl_channel_credentials = SslCredentials().ssl_credentials 

238 

239 else: 

240 if client_cert_source_for_mtls and not ssl_channel_credentials: 

241 cert, key = client_cert_source_for_mtls() 

242 self._ssl_channel_credentials = grpc.ssl_channel_credentials( 

243 certificate_chain=cert, private_key=key 

244 ) 

245 

246 # The base transport sets the host, credentials and scopes 

247 super().__init__( 

248 host=host, 

249 credentials=credentials, 

250 credentials_file=credentials_file, 

251 scopes=scopes, 

252 quota_project_id=quota_project_id, 

253 client_info=client_info, 

254 always_use_jwt_access=always_use_jwt_access, 

255 api_audience=api_audience, 

256 ) 

257 

258 if not self._grpc_channel: 

259 # initialize with the provided callable or the default channel 

260 channel_init = channel or type(self).create_channel 

261 self._grpc_channel = channel_init( 

262 self._host, 

263 # use the credentials which are saved 

264 credentials=self._credentials, 

265 # Set ``credentials_file`` to ``None`` here as 

266 # the credentials that we saved earlier should be used. 

267 credentials_file=None, 

268 scopes=self._scopes, 

269 ssl_credentials=self._ssl_channel_credentials, 

270 quota_project_id=quota_project_id, 

271 options=[ 

272 ("grpc.max_send_message_length", -1), 

273 ("grpc.max_receive_message_length", -1), 

274 ], 

275 ) 

276 

277 self._interceptor = _LoggingClientInterceptor() 

278 self._logged_channel = grpc.intercept_channel( 

279 self._grpc_channel, self._interceptor 

280 ) 

281 

282 # Wrap messages. This must be done after self._logged_channel exists 

283 self._prep_wrapped_messages(client_info) 

284 

285 @classmethod 

286 def create_channel( 

287 cls, 

288 host: str = "firestore.googleapis.com", 

289 credentials: Optional[ga_credentials.Credentials] = None, 

290 credentials_file: Optional[str] = None, 

291 scopes: Optional[Sequence[str]] = None, 

292 quota_project_id: Optional[str] = None, 

293 **kwargs, 

294 ) -> grpc.Channel: 

295 """Create and return a gRPC channel object. 

296 Args: 

297 host (Optional[str]): The host for the channel to use. 

298 credentials (Optional[~.Credentials]): The 

299 authorization credentials to attach to requests. These 

300 credentials identify this application to the service. If 

301 none are specified, the client will attempt to ascertain 

302 the credentials from the environment. 

303 credentials_file (Optional[str]): Deprecated. A file with credentials that can 

304 be loaded with :func:`google.auth.load_credentials_from_file`. 

305 This argument is mutually exclusive with credentials. This argument will be 

306 removed in the next major version of this library. 

307 scopes (Optional[Sequence[str]]): A optional list of scopes needed for this 

308 service. These are only used when credentials are not specified and 

309 are passed to :func:`google.auth.default`. 

310 quota_project_id (Optional[str]): An optional project to use for billing 

311 and quota. 

312 kwargs (Optional[dict]): Keyword arguments, which are passed to the 

313 channel creation. 

314 Returns: 

315 grpc.Channel: A gRPC channel object. 

316 

317 Raises: 

318 google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` 

319 and ``credentials_file`` are passed. 

320 """ 

321 

322 return grpc_helpers.create_channel( 

323 host, 

324 credentials=credentials, 

325 credentials_file=credentials_file, 

326 quota_project_id=quota_project_id, 

327 default_scopes=cls.AUTH_SCOPES, 

328 scopes=scopes, 

329 default_host=cls.DEFAULT_HOST, 

330 **kwargs, 

331 ) 

332 

333 @property 

334 def grpc_channel(self) -> grpc.Channel: 

335 """Return the channel designed to connect to this service.""" 

336 return self._grpc_channel 

337 

338 @property 

339 def get_document( 

340 self, 

341 ) -> Callable[[firestore.GetDocumentRequest], document.Document]: 

342 r"""Return a callable for the get document method over gRPC. 

343 

344 Gets a single document. 

345 

346 Returns: 

347 Callable[[~.GetDocumentRequest], 

348 ~.Document]: 

349 A function that, when called, will call the underlying RPC 

350 on the server. 

351 """ 

352 # Generate a "stub function" on-the-fly which will actually make 

353 # the request. 

354 # gRPC handles serialization and deserialization, so we just need 

355 # to pass in the functions for each. 

356 if "get_document" not in self._stubs: 

357 self._stubs["get_document"] = self._logged_channel.unary_unary( 

358 "/google.firestore.v1.Firestore/GetDocument", 

359 request_serializer=firestore.GetDocumentRequest.serialize, 

360 response_deserializer=document.Document.deserialize, 

361 ) 

362 return self._stubs["get_document"] 

363 

364 @property 

365 def list_documents( 

366 self, 

367 ) -> Callable[[firestore.ListDocumentsRequest], firestore.ListDocumentsResponse]: 

368 r"""Return a callable for the list documents method over gRPC. 

369 

370 Lists documents. 

371 

372 Returns: 

373 Callable[[~.ListDocumentsRequest], 

374 ~.ListDocumentsResponse]: 

375 A function that, when called, will call the underlying RPC 

376 on the server. 

377 """ 

378 # Generate a "stub function" on-the-fly which will actually make 

379 # the request. 

380 # gRPC handles serialization and deserialization, so we just need 

381 # to pass in the functions for each. 

382 if "list_documents" not in self._stubs: 

383 self._stubs["list_documents"] = self._logged_channel.unary_unary( 

384 "/google.firestore.v1.Firestore/ListDocuments", 

385 request_serializer=firestore.ListDocumentsRequest.serialize, 

386 response_deserializer=firestore.ListDocumentsResponse.deserialize, 

387 ) 

388 return self._stubs["list_documents"] 

389 

390 @property 

391 def update_document( 

392 self, 

393 ) -> Callable[[firestore.UpdateDocumentRequest], gf_document.Document]: 

394 r"""Return a callable for the update document method over gRPC. 

395 

396 Updates or inserts a document. 

397 

398 Returns: 

399 Callable[[~.UpdateDocumentRequest], 

400 ~.Document]: 

401 A function that, when called, will call the underlying RPC 

402 on the server. 

403 """ 

404 # Generate a "stub function" on-the-fly which will actually make 

405 # the request. 

406 # gRPC handles serialization and deserialization, so we just need 

407 # to pass in the functions for each. 

408 if "update_document" not in self._stubs: 

409 self._stubs["update_document"] = self._logged_channel.unary_unary( 

410 "/google.firestore.v1.Firestore/UpdateDocument", 

411 request_serializer=firestore.UpdateDocumentRequest.serialize, 

412 response_deserializer=gf_document.Document.deserialize, 

413 ) 

414 return self._stubs["update_document"] 

415 

416 @property 

417 def delete_document( 

418 self, 

419 ) -> Callable[[firestore.DeleteDocumentRequest], empty_pb2.Empty]: 

420 r"""Return a callable for the delete document method over gRPC. 

421 

422 Deletes a document. 

423 

424 Returns: 

425 Callable[[~.DeleteDocumentRequest], 

426 ~.Empty]: 

427 A function that, when called, will call the underlying RPC 

428 on the server. 

429 """ 

430 # Generate a "stub function" on-the-fly which will actually make 

431 # the request. 

432 # gRPC handles serialization and deserialization, so we just need 

433 # to pass in the functions for each. 

434 if "delete_document" not in self._stubs: 

435 self._stubs["delete_document"] = self._logged_channel.unary_unary( 

436 "/google.firestore.v1.Firestore/DeleteDocument", 

437 request_serializer=firestore.DeleteDocumentRequest.serialize, 

438 response_deserializer=empty_pb2.Empty.FromString, 

439 ) 

440 return self._stubs["delete_document"] 

441 

442 @property 

443 def batch_get_documents( 

444 self, 

445 ) -> Callable[ 

446 [firestore.BatchGetDocumentsRequest], firestore.BatchGetDocumentsResponse 

447 ]: 

448 r"""Return a callable for the batch get documents method over gRPC. 

449 

450 Gets multiple documents. 

451 

452 Documents returned by this method are not guaranteed to 

453 be returned in the same order that they were requested. 

454 

455 Returns: 

456 Callable[[~.BatchGetDocumentsRequest], 

457 ~.BatchGetDocumentsResponse]: 

458 A function that, when called, will call the underlying RPC 

459 on the server. 

460 """ 

461 # Generate a "stub function" on-the-fly which will actually make 

462 # the request. 

463 # gRPC handles serialization and deserialization, so we just need 

464 # to pass in the functions for each. 

465 if "batch_get_documents" not in self._stubs: 

466 self._stubs["batch_get_documents"] = self._logged_channel.unary_stream( 

467 "/google.firestore.v1.Firestore/BatchGetDocuments", 

468 request_serializer=firestore.BatchGetDocumentsRequest.serialize, 

469 response_deserializer=firestore.BatchGetDocumentsResponse.deserialize, 

470 ) 

471 return self._stubs["batch_get_documents"] 

472 

473 @property 

474 def begin_transaction( 

475 self, 

476 ) -> Callable[ 

477 [firestore.BeginTransactionRequest], firestore.BeginTransactionResponse 

478 ]: 

479 r"""Return a callable for the begin transaction method over gRPC. 

480 

481 Starts a new transaction. 

482 

483 Returns: 

484 Callable[[~.BeginTransactionRequest], 

485 ~.BeginTransactionResponse]: 

486 A function that, when called, will call the underlying RPC 

487 on the server. 

488 """ 

489 # Generate a "stub function" on-the-fly which will actually make 

490 # the request. 

491 # gRPC handles serialization and deserialization, so we just need 

492 # to pass in the functions for each. 

493 if "begin_transaction" not in self._stubs: 

494 self._stubs["begin_transaction"] = self._logged_channel.unary_unary( 

495 "/google.firestore.v1.Firestore/BeginTransaction", 

496 request_serializer=firestore.BeginTransactionRequest.serialize, 

497 response_deserializer=firestore.BeginTransactionResponse.deserialize, 

498 ) 

499 return self._stubs["begin_transaction"] 

500 

501 @property 

502 def commit(self) -> Callable[[firestore.CommitRequest], firestore.CommitResponse]: 

503 r"""Return a callable for the commit method over gRPC. 

504 

505 Commits a transaction, while optionally updating 

506 documents. 

507 

508 Returns: 

509 Callable[[~.CommitRequest], 

510 ~.CommitResponse]: 

511 A function that, when called, will call the underlying RPC 

512 on the server. 

513 """ 

514 # Generate a "stub function" on-the-fly which will actually make 

515 # the request. 

516 # gRPC handles serialization and deserialization, so we just need 

517 # to pass in the functions for each. 

518 if "commit" not in self._stubs: 

519 self._stubs["commit"] = self._logged_channel.unary_unary( 

520 "/google.firestore.v1.Firestore/Commit", 

521 request_serializer=firestore.CommitRequest.serialize, 

522 response_deserializer=firestore.CommitResponse.deserialize, 

523 ) 

524 return self._stubs["commit"] 

525 

526 @property 

527 def rollback(self) -> Callable[[firestore.RollbackRequest], empty_pb2.Empty]: 

528 r"""Return a callable for the rollback method over gRPC. 

529 

530 Rolls back a transaction. 

531 

532 Returns: 

533 Callable[[~.RollbackRequest], 

534 ~.Empty]: 

535 A function that, when called, will call the underlying RPC 

536 on the server. 

537 """ 

538 # Generate a "stub function" on-the-fly which will actually make 

539 # the request. 

540 # gRPC handles serialization and deserialization, so we just need 

541 # to pass in the functions for each. 

542 if "rollback" not in self._stubs: 

543 self._stubs["rollback"] = self._logged_channel.unary_unary( 

544 "/google.firestore.v1.Firestore/Rollback", 

545 request_serializer=firestore.RollbackRequest.serialize, 

546 response_deserializer=empty_pb2.Empty.FromString, 

547 ) 

548 return self._stubs["rollback"] 

549 

550 @property 

551 def run_query( 

552 self, 

553 ) -> Callable[[firestore.RunQueryRequest], firestore.RunQueryResponse]: 

554 r"""Return a callable for the run query method over gRPC. 

555 

556 Runs a query. 

557 

558 Returns: 

559 Callable[[~.RunQueryRequest], 

560 ~.RunQueryResponse]: 

561 A function that, when called, will call the underlying RPC 

562 on the server. 

563 """ 

564 # Generate a "stub function" on-the-fly which will actually make 

565 # the request. 

566 # gRPC handles serialization and deserialization, so we just need 

567 # to pass in the functions for each. 

568 if "run_query" not in self._stubs: 

569 self._stubs["run_query"] = self._logged_channel.unary_stream( 

570 "/google.firestore.v1.Firestore/RunQuery", 

571 request_serializer=firestore.RunQueryRequest.serialize, 

572 response_deserializer=firestore.RunQueryResponse.deserialize, 

573 ) 

574 return self._stubs["run_query"] 

575 

576 @property 

577 def execute_pipeline( 

578 self, 

579 ) -> Callable[ 

580 [firestore.ExecutePipelineRequest], firestore.ExecutePipelineResponse 

581 ]: 

582 r"""Return a callable for the execute pipeline method over gRPC. 

583 

584 Executes a pipeline query. 

585 

586 Returns: 

587 Callable[[~.ExecutePipelineRequest], 

588 ~.ExecutePipelineResponse]: 

589 A function that, when called, will call the underlying RPC 

590 on the server. 

591 """ 

592 # Generate a "stub function" on-the-fly which will actually make 

593 # the request. 

594 # gRPC handles serialization and deserialization, so we just need 

595 # to pass in the functions for each. 

596 if "execute_pipeline" not in self._stubs: 

597 self._stubs["execute_pipeline"] = self._logged_channel.unary_stream( 

598 "/google.firestore.v1.Firestore/ExecutePipeline", 

599 request_serializer=firestore.ExecutePipelineRequest.serialize, 

600 response_deserializer=firestore.ExecutePipelineResponse.deserialize, 

601 ) 

602 return self._stubs["execute_pipeline"] 

603 

604 @property 

605 def run_aggregation_query( 

606 self, 

607 ) -> Callable[ 

608 [firestore.RunAggregationQueryRequest], firestore.RunAggregationQueryResponse 

609 ]: 

610 r"""Return a callable for the run aggregation query method over gRPC. 

611 

612 Runs an aggregation query. 

613 

614 Rather than producing [Document][google.firestore.v1.Document] 

615 results like 

616 [Firestore.RunQuery][google.firestore.v1.Firestore.RunQuery], 

617 this API allows running an aggregation to produce a series of 

618 [AggregationResult][google.firestore.v1.AggregationResult] 

619 server-side. 

620 

621 High-Level Example: 

622 

623 :: 

624 

625 -- Return the number of documents in table given a filter. 

626 SELECT COUNT(*) FROM ( SELECT * FROM k where a = true ); 

627 

628 Returns: 

629 Callable[[~.RunAggregationQueryRequest], 

630 ~.RunAggregationQueryResponse]: 

631 A function that, when called, will call the underlying RPC 

632 on the server. 

633 """ 

634 # Generate a "stub function" on-the-fly which will actually make 

635 # the request. 

636 # gRPC handles serialization and deserialization, so we just need 

637 # to pass in the functions for each. 

638 if "run_aggregation_query" not in self._stubs: 

639 self._stubs["run_aggregation_query"] = self._logged_channel.unary_stream( 

640 "/google.firestore.v1.Firestore/RunAggregationQuery", 

641 request_serializer=firestore.RunAggregationQueryRequest.serialize, 

642 response_deserializer=firestore.RunAggregationQueryResponse.deserialize, 

643 ) 

644 return self._stubs["run_aggregation_query"] 

645 

646 @property 

647 def partition_query( 

648 self, 

649 ) -> Callable[[firestore.PartitionQueryRequest], firestore.PartitionQueryResponse]: 

650 r"""Return a callable for the partition query method over gRPC. 

651 

652 Partitions a query by returning partition cursors 

653 that can be used to run the query in parallel. The 

654 returned partition cursors are split points that can be 

655 used by RunQuery as starting/end points for the query 

656 results. 

657 

658 Returns: 

659 Callable[[~.PartitionQueryRequest], 

660 ~.PartitionQueryResponse]: 

661 A function that, when called, will call the underlying RPC 

662 on the server. 

663 """ 

664 # Generate a "stub function" on-the-fly which will actually make 

665 # the request. 

666 # gRPC handles serialization and deserialization, so we just need 

667 # to pass in the functions for each. 

668 if "partition_query" not in self._stubs: 

669 self._stubs["partition_query"] = self._logged_channel.unary_unary( 

670 "/google.firestore.v1.Firestore/PartitionQuery", 

671 request_serializer=firestore.PartitionQueryRequest.serialize, 

672 response_deserializer=firestore.PartitionQueryResponse.deserialize, 

673 ) 

674 return self._stubs["partition_query"] 

675 

676 @property 

677 def write(self) -> Callable[[firestore.WriteRequest], firestore.WriteResponse]: 

678 r"""Return a callable for the write method over gRPC. 

679 

680 Streams batches of document updates and deletes, in 

681 order. This method is only available via gRPC or 

682 WebChannel (not REST). 

683 

684 Returns: 

685 Callable[[~.WriteRequest], 

686 ~.WriteResponse]: 

687 A function that, when called, will call the underlying RPC 

688 on the server. 

689 """ 

690 # Generate a "stub function" on-the-fly which will actually make 

691 # the request. 

692 # gRPC handles serialization and deserialization, so we just need 

693 # to pass in the functions for each. 

694 if "write" not in self._stubs: 

695 self._stubs["write"] = self._logged_channel.stream_stream( 

696 "/google.firestore.v1.Firestore/Write", 

697 request_serializer=firestore.WriteRequest.serialize, 

698 response_deserializer=firestore.WriteResponse.deserialize, 

699 ) 

700 return self._stubs["write"] 

701 

702 @property 

703 def listen(self) -> Callable[[firestore.ListenRequest], firestore.ListenResponse]: 

704 r"""Return a callable for the listen method over gRPC. 

705 

706 Listens to changes. This method is only available via 

707 gRPC or WebChannel (not REST). 

708 

709 Returns: 

710 Callable[[~.ListenRequest], 

711 ~.ListenResponse]: 

712 A function that, when called, will call the underlying RPC 

713 on the server. 

714 """ 

715 # Generate a "stub function" on-the-fly which will actually make 

716 # the request. 

717 # gRPC handles serialization and deserialization, so we just need 

718 # to pass in the functions for each. 

719 if "listen" not in self._stubs: 

720 self._stubs["listen"] = self._logged_channel.stream_stream( 

721 "/google.firestore.v1.Firestore/Listen", 

722 request_serializer=firestore.ListenRequest.serialize, 

723 response_deserializer=firestore.ListenResponse.deserialize, 

724 ) 

725 return self._stubs["listen"] 

726 

727 @property 

728 def list_collection_ids( 

729 self, 

730 ) -> Callable[ 

731 [firestore.ListCollectionIdsRequest], firestore.ListCollectionIdsResponse 

732 ]: 

733 r"""Return a callable for the list collection ids method over gRPC. 

734 

735 Lists all the collection IDs underneath a document. 

736 

737 Returns: 

738 Callable[[~.ListCollectionIdsRequest], 

739 ~.ListCollectionIdsResponse]: 

740 A function that, when called, will call the underlying RPC 

741 on the server. 

742 """ 

743 # Generate a "stub function" on-the-fly which will actually make 

744 # the request. 

745 # gRPC handles serialization and deserialization, so we just need 

746 # to pass in the functions for each. 

747 if "list_collection_ids" not in self._stubs: 

748 self._stubs["list_collection_ids"] = self._logged_channel.unary_unary( 

749 "/google.firestore.v1.Firestore/ListCollectionIds", 

750 request_serializer=firestore.ListCollectionIdsRequest.serialize, 

751 response_deserializer=firestore.ListCollectionIdsResponse.deserialize, 

752 ) 

753 return self._stubs["list_collection_ids"] 

754 

755 @property 

756 def batch_write( 

757 self, 

758 ) -> Callable[[firestore.BatchWriteRequest], firestore.BatchWriteResponse]: 

759 r"""Return a callable for the batch write method over gRPC. 

760 

761 Applies a batch of write operations. 

762 

763 The BatchWrite method does not apply the write operations 

764 atomically and can apply them out of order. Method does not 

765 allow more than one write per document. Each write succeeds or 

766 fails independently. See the 

767 [BatchWriteResponse][google.firestore.v1.BatchWriteResponse] for 

768 the success status of each write. 

769 

770 If you require an atomically applied set of writes, use 

771 [Commit][google.firestore.v1.Firestore.Commit] instead. 

772 

773 Returns: 

774 Callable[[~.BatchWriteRequest], 

775 ~.BatchWriteResponse]: 

776 A function that, when called, will call the underlying RPC 

777 on the server. 

778 """ 

779 # Generate a "stub function" on-the-fly which will actually make 

780 # the request. 

781 # gRPC handles serialization and deserialization, so we just need 

782 # to pass in the functions for each. 

783 if "batch_write" not in self._stubs: 

784 self._stubs["batch_write"] = self._logged_channel.unary_unary( 

785 "/google.firestore.v1.Firestore/BatchWrite", 

786 request_serializer=firestore.BatchWriteRequest.serialize, 

787 response_deserializer=firestore.BatchWriteResponse.deserialize, 

788 ) 

789 return self._stubs["batch_write"] 

790 

791 @property 

792 def create_document( 

793 self, 

794 ) -> Callable[[firestore.CreateDocumentRequest], document.Document]: 

795 r"""Return a callable for the create document method over gRPC. 

796 

797 Creates a new document. 

798 

799 Returns: 

800 Callable[[~.CreateDocumentRequest], 

801 ~.Document]: 

802 A function that, when called, will call the underlying RPC 

803 on the server. 

804 """ 

805 # Generate a "stub function" on-the-fly which will actually make 

806 # the request. 

807 # gRPC handles serialization and deserialization, so we just need 

808 # to pass in the functions for each. 

809 if "create_document" not in self._stubs: 

810 self._stubs["create_document"] = self._logged_channel.unary_unary( 

811 "/google.firestore.v1.Firestore/CreateDocument", 

812 request_serializer=firestore.CreateDocumentRequest.serialize, 

813 response_deserializer=document.Document.deserialize, 

814 ) 

815 return self._stubs["create_document"] 

816 

817 def close(self): 

818 self._logged_channel.close() 

819 

820 @property 

821 def delete_operation( 

822 self, 

823 ) -> Callable[[operations_pb2.DeleteOperationRequest], None]: 

824 r"""Return a callable for the delete_operation method over gRPC.""" 

825 # Generate a "stub function" on-the-fly which will actually make 

826 # the request. 

827 # gRPC handles serialization and deserialization, so we just need 

828 # to pass in the functions for each. 

829 if "delete_operation" not in self._stubs: 

830 self._stubs["delete_operation"] = self._logged_channel.unary_unary( 

831 "/google.longrunning.Operations/DeleteOperation", 

832 request_serializer=operations_pb2.DeleteOperationRequest.SerializeToString, 

833 response_deserializer=None, 

834 ) 

835 return self._stubs["delete_operation"] 

836 

837 @property 

838 def cancel_operation( 

839 self, 

840 ) -> Callable[[operations_pb2.CancelOperationRequest], None]: 

841 r"""Return a callable for the cancel_operation method over gRPC.""" 

842 # Generate a "stub function" on-the-fly which will actually make 

843 # the request. 

844 # gRPC handles serialization and deserialization, so we just need 

845 # to pass in the functions for each. 

846 if "cancel_operation" not in self._stubs: 

847 self._stubs["cancel_operation"] = self._logged_channel.unary_unary( 

848 "/google.longrunning.Operations/CancelOperation", 

849 request_serializer=operations_pb2.CancelOperationRequest.SerializeToString, 

850 response_deserializer=None, 

851 ) 

852 return self._stubs["cancel_operation"] 

853 

854 @property 

855 def get_operation( 

856 self, 

857 ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: 

858 r"""Return a callable for the get_operation method over gRPC.""" 

859 # Generate a "stub function" on-the-fly which will actually make 

860 # the request. 

861 # gRPC handles serialization and deserialization, so we just need 

862 # to pass in the functions for each. 

863 if "get_operation" not in self._stubs: 

864 self._stubs["get_operation"] = self._logged_channel.unary_unary( 

865 "/google.longrunning.Operations/GetOperation", 

866 request_serializer=operations_pb2.GetOperationRequest.SerializeToString, 

867 response_deserializer=operations_pb2.Operation.FromString, 

868 ) 

869 return self._stubs["get_operation"] 

870 

871 @property 

872 def list_operations( 

873 self, 

874 ) -> Callable[ 

875 [operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse 

876 ]: 

877 r"""Return a callable for the list_operations method over gRPC.""" 

878 # Generate a "stub function" on-the-fly which will actually make 

879 # the request. 

880 # gRPC handles serialization and deserialization, so we just need 

881 # to pass in the functions for each. 

882 if "list_operations" not in self._stubs: 

883 self._stubs["list_operations"] = self._logged_channel.unary_unary( 

884 "/google.longrunning.Operations/ListOperations", 

885 request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, 

886 response_deserializer=operations_pb2.ListOperationsResponse.FromString, 

887 ) 

888 return self._stubs["list_operations"] 

889 

890 @property 

891 def kind(self) -> str: 

892 return "grpc" 

893 

894 

895__all__ = ("FirestoreGrpcTransport",)