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

168 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 run_aggregation_query( 

578 self, 

579 ) -> Callable[ 

580 [firestore.RunAggregationQueryRequest], firestore.RunAggregationQueryResponse 

581 ]: 

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

583 

584 Runs an aggregation query. 

585 

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

587 results like 

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

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

590 [AggregationResult][google.firestore.v1.AggregationResult] 

591 server-side. 

592 

593 High-Level Example: 

594 

595 :: 

596 

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

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

599 

600 Returns: 

601 Callable[[~.RunAggregationQueryRequest], 

602 ~.RunAggregationQueryResponse]: 

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

604 on the server. 

605 """ 

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

607 # the request. 

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

609 # to pass in the functions for each. 

610 if "run_aggregation_query" not in self._stubs: 

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

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

613 request_serializer=firestore.RunAggregationQueryRequest.serialize, 

614 response_deserializer=firestore.RunAggregationQueryResponse.deserialize, 

615 ) 

616 return self._stubs["run_aggregation_query"] 

617 

618 @property 

619 def partition_query( 

620 self, 

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

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

623 

624 Partitions a query by returning partition cursors 

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

626 returned partition cursors are split points that can be 

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

628 results. 

629 

630 Returns: 

631 Callable[[~.PartitionQueryRequest], 

632 ~.PartitionQueryResponse]: 

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

634 on the server. 

635 """ 

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

637 # the request. 

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

639 # to pass in the functions for each. 

640 if "partition_query" not in self._stubs: 

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

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

643 request_serializer=firestore.PartitionQueryRequest.serialize, 

644 response_deserializer=firestore.PartitionQueryResponse.deserialize, 

645 ) 

646 return self._stubs["partition_query"] 

647 

648 @property 

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

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

651 

652 Streams batches of document updates and deletes, in 

653 order. This method is only available via gRPC or 

654 WebChannel (not REST). 

655 

656 Returns: 

657 Callable[[~.WriteRequest], 

658 ~.WriteResponse]: 

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

660 on the server. 

661 """ 

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

663 # the request. 

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

665 # to pass in the functions for each. 

666 if "write" not in self._stubs: 

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

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

669 request_serializer=firestore.WriteRequest.serialize, 

670 response_deserializer=firestore.WriteResponse.deserialize, 

671 ) 

672 return self._stubs["write"] 

673 

674 @property 

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

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

677 

678 Listens to changes. This method is only available via 

679 gRPC or WebChannel (not REST). 

680 

681 Returns: 

682 Callable[[~.ListenRequest], 

683 ~.ListenResponse]: 

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

685 on the server. 

686 """ 

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

688 # the request. 

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

690 # to pass in the functions for each. 

691 if "listen" not in self._stubs: 

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

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

694 request_serializer=firestore.ListenRequest.serialize, 

695 response_deserializer=firestore.ListenResponse.deserialize, 

696 ) 

697 return self._stubs["listen"] 

698 

699 @property 

700 def list_collection_ids( 

701 self, 

702 ) -> Callable[ 

703 [firestore.ListCollectionIdsRequest], firestore.ListCollectionIdsResponse 

704 ]: 

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

706 

707 Lists all the collection IDs underneath a document. 

708 

709 Returns: 

710 Callable[[~.ListCollectionIdsRequest], 

711 ~.ListCollectionIdsResponse]: 

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 "list_collection_ids" not in self._stubs: 

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

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

722 request_serializer=firestore.ListCollectionIdsRequest.serialize, 

723 response_deserializer=firestore.ListCollectionIdsResponse.deserialize, 

724 ) 

725 return self._stubs["list_collection_ids"] 

726 

727 @property 

728 def batch_write( 

729 self, 

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

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

732 

733 Applies a batch of write operations. 

734 

735 The BatchWrite method does not apply the write operations 

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

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

738 fails independently. See the 

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

740 the success status of each write. 

741 

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

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

744 

745 Returns: 

746 Callable[[~.BatchWriteRequest], 

747 ~.BatchWriteResponse]: 

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

749 on the server. 

750 """ 

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

752 # the request. 

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

754 # to pass in the functions for each. 

755 if "batch_write" not in self._stubs: 

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

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

758 request_serializer=firestore.BatchWriteRequest.serialize, 

759 response_deserializer=firestore.BatchWriteResponse.deserialize, 

760 ) 

761 return self._stubs["batch_write"] 

762 

763 @property 

764 def create_document( 

765 self, 

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

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

768 

769 Creates a new document. 

770 

771 Returns: 

772 Callable[[~.CreateDocumentRequest], 

773 ~.Document]: 

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

775 on the server. 

776 """ 

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

778 # the request. 

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

780 # to pass in the functions for each. 

781 if "create_document" not in self._stubs: 

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

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

784 request_serializer=firestore.CreateDocumentRequest.serialize, 

785 response_deserializer=document.Document.deserialize, 

786 ) 

787 return self._stubs["create_document"] 

788 

789 def close(self): 

790 self._logged_channel.close() 

791 

792 @property 

793 def delete_operation( 

794 self, 

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

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

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

798 # the request. 

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

800 # to pass in the functions for each. 

801 if "delete_operation" not in self._stubs: 

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

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

804 request_serializer=operations_pb2.DeleteOperationRequest.SerializeToString, 

805 response_deserializer=None, 

806 ) 

807 return self._stubs["delete_operation"] 

808 

809 @property 

810 def cancel_operation( 

811 self, 

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

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

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

815 # the request. 

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

817 # to pass in the functions for each. 

818 if "cancel_operation" not in self._stubs: 

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

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

821 request_serializer=operations_pb2.CancelOperationRequest.SerializeToString, 

822 response_deserializer=None, 

823 ) 

824 return self._stubs["cancel_operation"] 

825 

826 @property 

827 def get_operation( 

828 self, 

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

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

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

832 # the request. 

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

834 # to pass in the functions for each. 

835 if "get_operation" not in self._stubs: 

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

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

838 request_serializer=operations_pb2.GetOperationRequest.SerializeToString, 

839 response_deserializer=operations_pb2.Operation.FromString, 

840 ) 

841 return self._stubs["get_operation"] 

842 

843 @property 

844 def list_operations( 

845 self, 

846 ) -> Callable[ 

847 [operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse 

848 ]: 

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

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

851 # the request. 

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

853 # to pass in the functions for each. 

854 if "list_operations" not in self._stubs: 

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

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

857 request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, 

858 response_deserializer=operations_pb2.ListOperationsResponse.FromString, 

859 ) 

860 return self._stubs["list_operations"] 

861 

862 @property 

863 def kind(self) -> str: 

864 return "grpc" 

865 

866 

867__all__ = ("FirestoreGrpcTransport",)