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]): 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 scopes (Optional(Sequence[str])): A list of scopes. This argument is 

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

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

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

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

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

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

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

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

179 a mutual TLS channel with client SSL credentials from 

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

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

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

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

184 ``api_mtls_endpoint`` is None. 

185 ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials 

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

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

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

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

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

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

192 and quota. 

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

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

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

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

197 your own client library. 

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

199 be used for service account credentials. 

200 

201 Raises: 

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

203 creation failed for any reason. 

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

205 and ``credentials_file`` are passed. 

206 """ 

207 self._grpc_channel = None 

208 self._ssl_channel_credentials = ssl_channel_credentials 

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

210 

211 if api_mtls_endpoint: 

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

213 if client_cert_source: 

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

215 

216 if isinstance(channel, grpc.Channel): 

217 # Ignore credentials if a channel was passed. 

218 credentials = None 

219 self._ignore_credentials = True 

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

221 self._grpc_channel = channel 

222 self._ssl_channel_credentials = None 

223 

224 else: 

225 if api_mtls_endpoint: 

226 host = api_mtls_endpoint 

227 

228 # Create SSL credentials with client_cert_source or application 

229 # default SSL credentials. 

230 if client_cert_source: 

231 cert, key = client_cert_source() 

232 self._ssl_channel_credentials = grpc.ssl_channel_credentials( 

233 certificate_chain=cert, private_key=key 

234 ) 

235 else: 

236 self._ssl_channel_credentials = SslCredentials().ssl_credentials 

237 

238 else: 

239 if client_cert_source_for_mtls and not ssl_channel_credentials: 

240 cert, key = client_cert_source_for_mtls() 

241 self._ssl_channel_credentials = grpc.ssl_channel_credentials( 

242 certificate_chain=cert, private_key=key 

243 ) 

244 

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

246 super().__init__( 

247 host=host, 

248 credentials=credentials, 

249 credentials_file=credentials_file, 

250 scopes=scopes, 

251 quota_project_id=quota_project_id, 

252 client_info=client_info, 

253 always_use_jwt_access=always_use_jwt_access, 

254 api_audience=api_audience, 

255 ) 

256 

257 if not self._grpc_channel: 

258 # initialize with the provided callable or the default channel 

259 channel_init = channel or type(self).create_channel 

260 self._grpc_channel = channel_init( 

261 self._host, 

262 # use the credentials which are saved 

263 credentials=self._credentials, 

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

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

266 credentials_file=None, 

267 scopes=self._scopes, 

268 ssl_credentials=self._ssl_channel_credentials, 

269 quota_project_id=quota_project_id, 

270 options=[ 

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

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

273 ], 

274 ) 

275 

276 self._interceptor = _LoggingClientInterceptor() 

277 self._logged_channel = grpc.intercept_channel( 

278 self._grpc_channel, self._interceptor 

279 ) 

280 

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

282 self._prep_wrapped_messages(client_info) 

283 

284 @classmethod 

285 def create_channel( 

286 cls, 

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

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

289 credentials_file: Optional[str] = None, 

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

291 quota_project_id: Optional[str] = None, 

292 **kwargs, 

293 ) -> grpc.Channel: 

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

295 Args: 

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

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

298 authorization credentials to attach to requests. These 

299 credentials identify this application to the service. If 

300 none are specified, the client will attempt to ascertain 

301 the credentials from the environment. 

302 credentials_file (Optional[str]): A file with credentials that can 

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

304 This argument is mutually exclusive with credentials. 

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

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

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

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

309 and quota. 

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

311 channel creation. 

312 Returns: 

313 grpc.Channel: A gRPC channel object. 

314 

315 Raises: 

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

317 and ``credentials_file`` are passed. 

318 """ 

319 

320 return grpc_helpers.create_channel( 

321 host, 

322 credentials=credentials, 

323 credentials_file=credentials_file, 

324 quota_project_id=quota_project_id, 

325 default_scopes=cls.AUTH_SCOPES, 

326 scopes=scopes, 

327 default_host=cls.DEFAULT_HOST, 

328 **kwargs, 

329 ) 

330 

331 @property 

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

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

334 return self._grpc_channel 

335 

336 @property 

337 def get_document( 

338 self, 

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

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

341 

342 Gets a single document. 

343 

344 Returns: 

345 Callable[[~.GetDocumentRequest], 

346 ~.Document]: 

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

348 on the server. 

349 """ 

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

351 # the request. 

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

353 # to pass in the functions for each. 

354 if "get_document" not in self._stubs: 

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

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

357 request_serializer=firestore.GetDocumentRequest.serialize, 

358 response_deserializer=document.Document.deserialize, 

359 ) 

360 return self._stubs["get_document"] 

361 

362 @property 

363 def list_documents( 

364 self, 

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

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

367 

368 Lists documents. 

369 

370 Returns: 

371 Callable[[~.ListDocumentsRequest], 

372 ~.ListDocumentsResponse]: 

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

374 on the server. 

375 """ 

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

377 # the request. 

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

379 # to pass in the functions for each. 

380 if "list_documents" not in self._stubs: 

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

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

383 request_serializer=firestore.ListDocumentsRequest.serialize, 

384 response_deserializer=firestore.ListDocumentsResponse.deserialize, 

385 ) 

386 return self._stubs["list_documents"] 

387 

388 @property 

389 def update_document( 

390 self, 

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

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

393 

394 Updates or inserts a document. 

395 

396 Returns: 

397 Callable[[~.UpdateDocumentRequest], 

398 ~.Document]: 

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

400 on the server. 

401 """ 

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

403 # the request. 

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

405 # to pass in the functions for each. 

406 if "update_document" not in self._stubs: 

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

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

409 request_serializer=firestore.UpdateDocumentRequest.serialize, 

410 response_deserializer=gf_document.Document.deserialize, 

411 ) 

412 return self._stubs["update_document"] 

413 

414 @property 

415 def delete_document( 

416 self, 

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

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

419 

420 Deletes a document. 

421 

422 Returns: 

423 Callable[[~.DeleteDocumentRequest], 

424 ~.Empty]: 

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

426 on the server. 

427 """ 

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

429 # the request. 

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

431 # to pass in the functions for each. 

432 if "delete_document" not in self._stubs: 

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

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

435 request_serializer=firestore.DeleteDocumentRequest.serialize, 

436 response_deserializer=empty_pb2.Empty.FromString, 

437 ) 

438 return self._stubs["delete_document"] 

439 

440 @property 

441 def batch_get_documents( 

442 self, 

443 ) -> Callable[ 

444 [firestore.BatchGetDocumentsRequest], firestore.BatchGetDocumentsResponse 

445 ]: 

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

447 

448 Gets multiple documents. 

449 

450 Documents returned by this method are not guaranteed to 

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

452 

453 Returns: 

454 Callable[[~.BatchGetDocumentsRequest], 

455 ~.BatchGetDocumentsResponse]: 

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

457 on the server. 

458 """ 

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

460 # the request. 

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

462 # to pass in the functions for each. 

463 if "batch_get_documents" not in self._stubs: 

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

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

466 request_serializer=firestore.BatchGetDocumentsRequest.serialize, 

467 response_deserializer=firestore.BatchGetDocumentsResponse.deserialize, 

468 ) 

469 return self._stubs["batch_get_documents"] 

470 

471 @property 

472 def begin_transaction( 

473 self, 

474 ) -> Callable[ 

475 [firestore.BeginTransactionRequest], firestore.BeginTransactionResponse 

476 ]: 

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

478 

479 Starts a new transaction. 

480 

481 Returns: 

482 Callable[[~.BeginTransactionRequest], 

483 ~.BeginTransactionResponse]: 

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

485 on the server. 

486 """ 

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

488 # the request. 

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

490 # to pass in the functions for each. 

491 if "begin_transaction" not in self._stubs: 

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

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

494 request_serializer=firestore.BeginTransactionRequest.serialize, 

495 response_deserializer=firestore.BeginTransactionResponse.deserialize, 

496 ) 

497 return self._stubs["begin_transaction"] 

498 

499 @property 

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

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

502 

503 Commits a transaction, while optionally updating 

504 documents. 

505 

506 Returns: 

507 Callable[[~.CommitRequest], 

508 ~.CommitResponse]: 

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

510 on the server. 

511 """ 

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

513 # the request. 

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

515 # to pass in the functions for each. 

516 if "commit" not in self._stubs: 

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

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

519 request_serializer=firestore.CommitRequest.serialize, 

520 response_deserializer=firestore.CommitResponse.deserialize, 

521 ) 

522 return self._stubs["commit"] 

523 

524 @property 

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

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

527 

528 Rolls back a transaction. 

529 

530 Returns: 

531 Callable[[~.RollbackRequest], 

532 ~.Empty]: 

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

534 on the server. 

535 """ 

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

537 # the request. 

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

539 # to pass in the functions for each. 

540 if "rollback" not in self._stubs: 

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

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

543 request_serializer=firestore.RollbackRequest.serialize, 

544 response_deserializer=empty_pb2.Empty.FromString, 

545 ) 

546 return self._stubs["rollback"] 

547 

548 @property 

549 def run_query( 

550 self, 

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

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

553 

554 Runs a query. 

555 

556 Returns: 

557 Callable[[~.RunQueryRequest], 

558 ~.RunQueryResponse]: 

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

560 on the server. 

561 """ 

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

563 # the request. 

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

565 # to pass in the functions for each. 

566 if "run_query" not in self._stubs: 

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

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

569 request_serializer=firestore.RunQueryRequest.serialize, 

570 response_deserializer=firestore.RunQueryResponse.deserialize, 

571 ) 

572 return self._stubs["run_query"] 

573 

574 @property 

575 def run_aggregation_query( 

576 self, 

577 ) -> Callable[ 

578 [firestore.RunAggregationQueryRequest], firestore.RunAggregationQueryResponse 

579 ]: 

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

581 

582 Runs an aggregation query. 

583 

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

585 results like 

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

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

588 [AggregationResult][google.firestore.v1.AggregationResult] 

589 server-side. 

590 

591 High-Level Example: 

592 

593 :: 

594 

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

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

597 

598 Returns: 

599 Callable[[~.RunAggregationQueryRequest], 

600 ~.RunAggregationQueryResponse]: 

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

602 on the server. 

603 """ 

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

605 # the request. 

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

607 # to pass in the functions for each. 

608 if "run_aggregation_query" not in self._stubs: 

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

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

611 request_serializer=firestore.RunAggregationQueryRequest.serialize, 

612 response_deserializer=firestore.RunAggregationQueryResponse.deserialize, 

613 ) 

614 return self._stubs["run_aggregation_query"] 

615 

616 @property 

617 def partition_query( 

618 self, 

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

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

621 

622 Partitions a query by returning partition cursors 

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

624 returned partition cursors are split points that can be 

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

626 results. 

627 

628 Returns: 

629 Callable[[~.PartitionQueryRequest], 

630 ~.PartitionQueryResponse]: 

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

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

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

641 request_serializer=firestore.PartitionQueryRequest.serialize, 

642 response_deserializer=firestore.PartitionQueryResponse.deserialize, 

643 ) 

644 return self._stubs["partition_query"] 

645 

646 @property 

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

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

649 

650 Streams batches of document updates and deletes, in 

651 order. This method is only available via gRPC or 

652 WebChannel (not REST). 

653 

654 Returns: 

655 Callable[[~.WriteRequest], 

656 ~.WriteResponse]: 

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

658 on the server. 

659 """ 

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

661 # the request. 

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

663 # to pass in the functions for each. 

664 if "write" not in self._stubs: 

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

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

667 request_serializer=firestore.WriteRequest.serialize, 

668 response_deserializer=firestore.WriteResponse.deserialize, 

669 ) 

670 return self._stubs["write"] 

671 

672 @property 

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

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

675 

676 Listens to changes. This method is only available via 

677 gRPC or WebChannel (not REST). 

678 

679 Returns: 

680 Callable[[~.ListenRequest], 

681 ~.ListenResponse]: 

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

683 on the server. 

684 """ 

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

686 # the request. 

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

688 # to pass in the functions for each. 

689 if "listen" not in self._stubs: 

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

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

692 request_serializer=firestore.ListenRequest.serialize, 

693 response_deserializer=firestore.ListenResponse.deserialize, 

694 ) 

695 return self._stubs["listen"] 

696 

697 @property 

698 def list_collection_ids( 

699 self, 

700 ) -> Callable[ 

701 [firestore.ListCollectionIdsRequest], firestore.ListCollectionIdsResponse 

702 ]: 

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

704 

705 Lists all the collection IDs underneath a document. 

706 

707 Returns: 

708 Callable[[~.ListCollectionIdsRequest], 

709 ~.ListCollectionIdsResponse]: 

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

711 on the server. 

712 """ 

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

714 # the request. 

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

716 # to pass in the functions for each. 

717 if "list_collection_ids" not in self._stubs: 

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

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

720 request_serializer=firestore.ListCollectionIdsRequest.serialize, 

721 response_deserializer=firestore.ListCollectionIdsResponse.deserialize, 

722 ) 

723 return self._stubs["list_collection_ids"] 

724 

725 @property 

726 def batch_write( 

727 self, 

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

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

730 

731 Applies a batch of write operations. 

732 

733 The BatchWrite method does not apply the write operations 

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

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

736 fails independently. See the 

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

738 the success status of each write. 

739 

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

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

742 

743 Returns: 

744 Callable[[~.BatchWriteRequest], 

745 ~.BatchWriteResponse]: 

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

747 on the server. 

748 """ 

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

750 # the request. 

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

752 # to pass in the functions for each. 

753 if "batch_write" not in self._stubs: 

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

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

756 request_serializer=firestore.BatchWriteRequest.serialize, 

757 response_deserializer=firestore.BatchWriteResponse.deserialize, 

758 ) 

759 return self._stubs["batch_write"] 

760 

761 @property 

762 def create_document( 

763 self, 

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

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

766 

767 Creates a new document. 

768 

769 Returns: 

770 Callable[[~.CreateDocumentRequest], 

771 ~.Document]: 

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

773 on the server. 

774 """ 

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

776 # the request. 

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

778 # to pass in the functions for each. 

779 if "create_document" not in self._stubs: 

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

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

782 request_serializer=firestore.CreateDocumentRequest.serialize, 

783 response_deserializer=document.Document.deserialize, 

784 ) 

785 return self._stubs["create_document"] 

786 

787 def close(self): 

788 self._logged_channel.close() 

789 

790 @property 

791 def delete_operation( 

792 self, 

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

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

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

796 # the request. 

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

798 # to pass in the functions for each. 

799 if "delete_operation" not in self._stubs: 

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

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

802 request_serializer=operations_pb2.DeleteOperationRequest.SerializeToString, 

803 response_deserializer=None, 

804 ) 

805 return self._stubs["delete_operation"] 

806 

807 @property 

808 def cancel_operation( 

809 self, 

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

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

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

813 # the request. 

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

815 # to pass in the functions for each. 

816 if "cancel_operation" not in self._stubs: 

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

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

819 request_serializer=operations_pb2.CancelOperationRequest.SerializeToString, 

820 response_deserializer=None, 

821 ) 

822 return self._stubs["cancel_operation"] 

823 

824 @property 

825 def get_operation( 

826 self, 

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

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

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

830 # the request. 

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

832 # to pass in the functions for each. 

833 if "get_operation" not in self._stubs: 

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

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

836 request_serializer=operations_pb2.GetOperationRequest.SerializeToString, 

837 response_deserializer=operations_pb2.Operation.FromString, 

838 ) 

839 return self._stubs["get_operation"] 

840 

841 @property 

842 def list_operations( 

843 self, 

844 ) -> Callable[ 

845 [operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse 

846 ]: 

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

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

849 # the request. 

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

851 # to pass in the functions for each. 

852 if "list_operations" not in self._stubs: 

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

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

855 request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, 

856 response_deserializer=operations_pb2.ListOperationsResponse.FromString, 

857 ) 

858 return self._stubs["list_operations"] 

859 

860 @property 

861 def kind(self) -> str: 

862 return "grpc" 

863 

864 

865__all__ = ("FirestoreGrpcTransport",)