1# -*- coding: utf-8 -*-
2# Copyright 2023 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 warnings
17from typing import Callable, Dict, Optional, Sequence, Tuple, Union
18
19from google.api_core import grpc_helpers
20from google.api_core import gapic_v1
21import google.auth # type: ignore
22from google.auth import credentials as ga_credentials # type: ignore
23from google.auth.transport.grpc import SslCredentials # type: ignore
24
25import grpc # type: ignore
26
27from google.cloud.firestore_v1.types import document
28from google.cloud.firestore_v1.types import document as gf_document
29from google.cloud.firestore_v1.types import firestore
30from google.cloud.location import locations_pb2 # type: ignore
31from google.longrunning import operations_pb2 # type: ignore
32from google.protobuf import empty_pb2 # type: ignore
33from .base import FirestoreTransport, DEFAULT_CLIENT_INFO
34
35
36class FirestoreGrpcTransport(FirestoreTransport):
37 """gRPC backend transport for Firestore.
38
39 The Cloud Firestore service.
40
41 Cloud Firestore is a fast, fully managed, serverless,
42 cloud-native NoSQL document database that simplifies storing,
43 syncing, and querying data for your mobile, web, and IoT apps at
44 global scale. Its client libraries provide live synchronization
45 and offline support, while its security features and
46 integrations with Firebase and Google Cloud Platform accelerate
47 building truly serverless apps.
48
49 This class defines the same methods as the primary client, so the
50 primary client can load the underlying transport implementation
51 and call it.
52
53 It sends protocol buffers over the wire using gRPC (which is built on
54 top of HTTP/2); the ``grpcio`` package must be installed.
55 """
56
57 _stubs: Dict[str, Callable]
58
59 def __init__(
60 self,
61 *,
62 host: str = "firestore.googleapis.com",
63 credentials: Optional[ga_credentials.Credentials] = None,
64 credentials_file: Optional[str] = None,
65 scopes: Optional[Sequence[str]] = None,
66 channel: Optional[grpc.Channel] = None,
67 api_mtls_endpoint: Optional[str] = None,
68 client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None,
69 ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None,
70 client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None,
71 quota_project_id: Optional[str] = None,
72 client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
73 always_use_jwt_access: Optional[bool] = False,
74 api_audience: Optional[str] = None,
75 ) -> None:
76 """Instantiate the transport.
77
78 Args:
79 host (Optional[str]):
80 The hostname to connect to.
81 credentials (Optional[google.auth.credentials.Credentials]): The
82 authorization credentials to attach to requests. These
83 credentials identify the application to the service; if none
84 are specified, the client will attempt to ascertain the
85 credentials from the environment.
86 This argument is ignored if ``channel`` is provided.
87 credentials_file (Optional[str]): A file with credentials that can
88 be loaded with :func:`google.auth.load_credentials_from_file`.
89 This argument is ignored if ``channel`` is provided.
90 scopes (Optional(Sequence[str])): A list of scopes. This argument is
91 ignored if ``channel`` is provided.
92 channel (Optional[grpc.Channel]): A ``Channel`` instance through
93 which to make calls.
94 api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint.
95 If provided, it overrides the ``host`` argument and tries to create
96 a mutual TLS channel with client SSL credentials from
97 ``client_cert_source`` or application default SSL credentials.
98 client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]):
99 Deprecated. A callback to provide client SSL certificate bytes and
100 private key bytes, both in PEM format. It is ignored if
101 ``api_mtls_endpoint`` is None.
102 ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
103 for the grpc channel. It is ignored if ``channel`` is provided.
104 client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]):
105 A callback to provide client certificate bytes and private key bytes,
106 both in PEM format. It is used to configure a mutual TLS channel. It is
107 ignored if ``channel`` or ``ssl_channel_credentials`` is provided.
108 quota_project_id (Optional[str]): An optional project to use for billing
109 and quota.
110 client_info (google.api_core.gapic_v1.client_info.ClientInfo):
111 The client info used to send a user-agent string along with
112 API requests. If ``None``, then default info will be used.
113 Generally, you only need to set this if you're developing
114 your own client library.
115 always_use_jwt_access (Optional[bool]): Whether self signed JWT should
116 be used for service account credentials.
117
118 Raises:
119 google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
120 creation failed for any reason.
121 google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials``
122 and ``credentials_file`` are passed.
123 """
124 self._grpc_channel = None
125 self._ssl_channel_credentials = ssl_channel_credentials
126 self._stubs: Dict[str, Callable] = {}
127
128 if api_mtls_endpoint:
129 warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning)
130 if client_cert_source:
131 warnings.warn("client_cert_source is deprecated", DeprecationWarning)
132
133 if channel:
134 # Ignore credentials if a channel was passed.
135 credentials = False
136 # If a channel was explicitly provided, set it.
137 self._grpc_channel = channel
138 self._ssl_channel_credentials = None
139
140 else:
141 if api_mtls_endpoint:
142 host = api_mtls_endpoint
143
144 # Create SSL credentials with client_cert_source or application
145 # default SSL credentials.
146 if client_cert_source:
147 cert, key = client_cert_source()
148 self._ssl_channel_credentials = grpc.ssl_channel_credentials(
149 certificate_chain=cert, private_key=key
150 )
151 else:
152 self._ssl_channel_credentials = SslCredentials().ssl_credentials
153
154 else:
155 if client_cert_source_for_mtls and not ssl_channel_credentials:
156 cert, key = client_cert_source_for_mtls()
157 self._ssl_channel_credentials = grpc.ssl_channel_credentials(
158 certificate_chain=cert, private_key=key
159 )
160
161 # The base transport sets the host, credentials and scopes
162 super().__init__(
163 host=host,
164 credentials=credentials,
165 credentials_file=credentials_file,
166 scopes=scopes,
167 quota_project_id=quota_project_id,
168 client_info=client_info,
169 always_use_jwt_access=always_use_jwt_access,
170 api_audience=api_audience,
171 )
172
173 if not self._grpc_channel:
174 self._grpc_channel = type(self).create_channel(
175 self._host,
176 # use the credentials which are saved
177 credentials=self._credentials,
178 # Set ``credentials_file`` to ``None`` here as
179 # the credentials that we saved earlier should be used.
180 credentials_file=None,
181 scopes=self._scopes,
182 ssl_credentials=self._ssl_channel_credentials,
183 quota_project_id=quota_project_id,
184 options=[
185 ("grpc.max_send_message_length", -1),
186 ("grpc.max_receive_message_length", -1),
187 ],
188 )
189
190 # Wrap messages. This must be done after self._grpc_channel exists
191 self._prep_wrapped_messages(client_info)
192
193 @classmethod
194 def create_channel(
195 cls,
196 host: str = "firestore.googleapis.com",
197 credentials: Optional[ga_credentials.Credentials] = None,
198 credentials_file: Optional[str] = None,
199 scopes: Optional[Sequence[str]] = None,
200 quota_project_id: Optional[str] = None,
201 **kwargs,
202 ) -> grpc.Channel:
203 """Create and return a gRPC channel object.
204 Args:
205 host (Optional[str]): The host for the channel to use.
206 credentials (Optional[~.Credentials]): The
207 authorization credentials to attach to requests. These
208 credentials identify this application to the service. If
209 none are specified, the client will attempt to ascertain
210 the credentials from the environment.
211 credentials_file (Optional[str]): A file with credentials that can
212 be loaded with :func:`google.auth.load_credentials_from_file`.
213 This argument is mutually exclusive with credentials.
214 scopes (Optional[Sequence[str]]): A optional list of scopes needed for this
215 service. These are only used when credentials are not specified and
216 are passed to :func:`google.auth.default`.
217 quota_project_id (Optional[str]): An optional project to use for billing
218 and quota.
219 kwargs (Optional[dict]): Keyword arguments, which are passed to the
220 channel creation.
221 Returns:
222 grpc.Channel: A gRPC channel object.
223
224 Raises:
225 google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials``
226 and ``credentials_file`` are passed.
227 """
228
229 return grpc_helpers.create_channel(
230 host,
231 credentials=credentials,
232 credentials_file=credentials_file,
233 quota_project_id=quota_project_id,
234 default_scopes=cls.AUTH_SCOPES,
235 scopes=scopes,
236 default_host=cls.DEFAULT_HOST,
237 **kwargs,
238 )
239
240 @property
241 def grpc_channel(self) -> grpc.Channel:
242 """Return the channel designed to connect to this service."""
243 return self._grpc_channel
244
245 @property
246 def get_document(
247 self,
248 ) -> Callable[[firestore.GetDocumentRequest], document.Document]:
249 r"""Return a callable for the get document method over gRPC.
250
251 Gets a single document.
252
253 Returns:
254 Callable[[~.GetDocumentRequest],
255 ~.Document]:
256 A function that, when called, will call the underlying RPC
257 on the server.
258 """
259 # Generate a "stub function" on-the-fly which will actually make
260 # the request.
261 # gRPC handles serialization and deserialization, so we just need
262 # to pass in the functions for each.
263 if "get_document" not in self._stubs:
264 self._stubs["get_document"] = self.grpc_channel.unary_unary(
265 "/google.firestore.v1.Firestore/GetDocument",
266 request_serializer=firestore.GetDocumentRequest.serialize,
267 response_deserializer=document.Document.deserialize,
268 )
269 return self._stubs["get_document"]
270
271 @property
272 def list_documents(
273 self,
274 ) -> Callable[[firestore.ListDocumentsRequest], firestore.ListDocumentsResponse]:
275 r"""Return a callable for the list documents method over gRPC.
276
277 Lists documents.
278
279 Returns:
280 Callable[[~.ListDocumentsRequest],
281 ~.ListDocumentsResponse]:
282 A function that, when called, will call the underlying RPC
283 on the server.
284 """
285 # Generate a "stub function" on-the-fly which will actually make
286 # the request.
287 # gRPC handles serialization and deserialization, so we just need
288 # to pass in the functions for each.
289 if "list_documents" not in self._stubs:
290 self._stubs["list_documents"] = self.grpc_channel.unary_unary(
291 "/google.firestore.v1.Firestore/ListDocuments",
292 request_serializer=firestore.ListDocumentsRequest.serialize,
293 response_deserializer=firestore.ListDocumentsResponse.deserialize,
294 )
295 return self._stubs["list_documents"]
296
297 @property
298 def update_document(
299 self,
300 ) -> Callable[[firestore.UpdateDocumentRequest], gf_document.Document]:
301 r"""Return a callable for the update document method over gRPC.
302
303 Updates or inserts a document.
304
305 Returns:
306 Callable[[~.UpdateDocumentRequest],
307 ~.Document]:
308 A function that, when called, will call the underlying RPC
309 on the server.
310 """
311 # Generate a "stub function" on-the-fly which will actually make
312 # the request.
313 # gRPC handles serialization and deserialization, so we just need
314 # to pass in the functions for each.
315 if "update_document" not in self._stubs:
316 self._stubs["update_document"] = self.grpc_channel.unary_unary(
317 "/google.firestore.v1.Firestore/UpdateDocument",
318 request_serializer=firestore.UpdateDocumentRequest.serialize,
319 response_deserializer=gf_document.Document.deserialize,
320 )
321 return self._stubs["update_document"]
322
323 @property
324 def delete_document(
325 self,
326 ) -> Callable[[firestore.DeleteDocumentRequest], empty_pb2.Empty]:
327 r"""Return a callable for the delete document method over gRPC.
328
329 Deletes a document.
330
331 Returns:
332 Callable[[~.DeleteDocumentRequest],
333 ~.Empty]:
334 A function that, when called, will call the underlying RPC
335 on the server.
336 """
337 # Generate a "stub function" on-the-fly which will actually make
338 # the request.
339 # gRPC handles serialization and deserialization, so we just need
340 # to pass in the functions for each.
341 if "delete_document" not in self._stubs:
342 self._stubs["delete_document"] = self.grpc_channel.unary_unary(
343 "/google.firestore.v1.Firestore/DeleteDocument",
344 request_serializer=firestore.DeleteDocumentRequest.serialize,
345 response_deserializer=empty_pb2.Empty.FromString,
346 )
347 return self._stubs["delete_document"]
348
349 @property
350 def batch_get_documents(
351 self,
352 ) -> Callable[
353 [firestore.BatchGetDocumentsRequest], firestore.BatchGetDocumentsResponse
354 ]:
355 r"""Return a callable for the batch get documents method over gRPC.
356
357 Gets multiple documents.
358
359 Documents returned by this method are not guaranteed to
360 be returned in the same order that they were requested.
361
362 Returns:
363 Callable[[~.BatchGetDocumentsRequest],
364 ~.BatchGetDocumentsResponse]:
365 A function that, when called, will call the underlying RPC
366 on the server.
367 """
368 # Generate a "stub function" on-the-fly which will actually make
369 # the request.
370 # gRPC handles serialization and deserialization, so we just need
371 # to pass in the functions for each.
372 if "batch_get_documents" not in self._stubs:
373 self._stubs["batch_get_documents"] = self.grpc_channel.unary_stream(
374 "/google.firestore.v1.Firestore/BatchGetDocuments",
375 request_serializer=firestore.BatchGetDocumentsRequest.serialize,
376 response_deserializer=firestore.BatchGetDocumentsResponse.deserialize,
377 )
378 return self._stubs["batch_get_documents"]
379
380 @property
381 def begin_transaction(
382 self,
383 ) -> Callable[
384 [firestore.BeginTransactionRequest], firestore.BeginTransactionResponse
385 ]:
386 r"""Return a callable for the begin transaction method over gRPC.
387
388 Starts a new transaction.
389
390 Returns:
391 Callable[[~.BeginTransactionRequest],
392 ~.BeginTransactionResponse]:
393 A function that, when called, will call the underlying RPC
394 on the server.
395 """
396 # Generate a "stub function" on-the-fly which will actually make
397 # the request.
398 # gRPC handles serialization and deserialization, so we just need
399 # to pass in the functions for each.
400 if "begin_transaction" not in self._stubs:
401 self._stubs["begin_transaction"] = self.grpc_channel.unary_unary(
402 "/google.firestore.v1.Firestore/BeginTransaction",
403 request_serializer=firestore.BeginTransactionRequest.serialize,
404 response_deserializer=firestore.BeginTransactionResponse.deserialize,
405 )
406 return self._stubs["begin_transaction"]
407
408 @property
409 def commit(self) -> Callable[[firestore.CommitRequest], firestore.CommitResponse]:
410 r"""Return a callable for the commit method over gRPC.
411
412 Commits a transaction, while optionally updating
413 documents.
414
415 Returns:
416 Callable[[~.CommitRequest],
417 ~.CommitResponse]:
418 A function that, when called, will call the underlying RPC
419 on the server.
420 """
421 # Generate a "stub function" on-the-fly which will actually make
422 # the request.
423 # gRPC handles serialization and deserialization, so we just need
424 # to pass in the functions for each.
425 if "commit" not in self._stubs:
426 self._stubs["commit"] = self.grpc_channel.unary_unary(
427 "/google.firestore.v1.Firestore/Commit",
428 request_serializer=firestore.CommitRequest.serialize,
429 response_deserializer=firestore.CommitResponse.deserialize,
430 )
431 return self._stubs["commit"]
432
433 @property
434 def rollback(self) -> Callable[[firestore.RollbackRequest], empty_pb2.Empty]:
435 r"""Return a callable for the rollback method over gRPC.
436
437 Rolls back a transaction.
438
439 Returns:
440 Callable[[~.RollbackRequest],
441 ~.Empty]:
442 A function that, when called, will call the underlying RPC
443 on the server.
444 """
445 # Generate a "stub function" on-the-fly which will actually make
446 # the request.
447 # gRPC handles serialization and deserialization, so we just need
448 # to pass in the functions for each.
449 if "rollback" not in self._stubs:
450 self._stubs["rollback"] = self.grpc_channel.unary_unary(
451 "/google.firestore.v1.Firestore/Rollback",
452 request_serializer=firestore.RollbackRequest.serialize,
453 response_deserializer=empty_pb2.Empty.FromString,
454 )
455 return self._stubs["rollback"]
456
457 @property
458 def run_query(
459 self,
460 ) -> Callable[[firestore.RunQueryRequest], firestore.RunQueryResponse]:
461 r"""Return a callable for the run query method over gRPC.
462
463 Runs a query.
464
465 Returns:
466 Callable[[~.RunQueryRequest],
467 ~.RunQueryResponse]:
468 A function that, when called, will call the underlying RPC
469 on the server.
470 """
471 # Generate a "stub function" on-the-fly which will actually make
472 # the request.
473 # gRPC handles serialization and deserialization, so we just need
474 # to pass in the functions for each.
475 if "run_query" not in self._stubs:
476 self._stubs["run_query"] = self.grpc_channel.unary_stream(
477 "/google.firestore.v1.Firestore/RunQuery",
478 request_serializer=firestore.RunQueryRequest.serialize,
479 response_deserializer=firestore.RunQueryResponse.deserialize,
480 )
481 return self._stubs["run_query"]
482
483 @property
484 def run_aggregation_query(
485 self,
486 ) -> Callable[
487 [firestore.RunAggregationQueryRequest], firestore.RunAggregationQueryResponse
488 ]:
489 r"""Return a callable for the run aggregation query method over gRPC.
490
491 Runs an aggregation query.
492
493 Rather than producing [Document][google.firestore.v1.Document]
494 results like
495 [Firestore.RunQuery][google.firestore.v1.Firestore.RunQuery],
496 this API allows running an aggregation to produce a series of
497 [AggregationResult][google.firestore.v1.AggregationResult]
498 server-side.
499
500 High-Level Example:
501
502 ::
503
504 -- Return the number of documents in table given a filter.
505 SELECT COUNT(*) FROM ( SELECT * FROM k where a = true );
506
507 Returns:
508 Callable[[~.RunAggregationQueryRequest],
509 ~.RunAggregationQueryResponse]:
510 A function that, when called, will call the underlying RPC
511 on the server.
512 """
513 # Generate a "stub function" on-the-fly which will actually make
514 # the request.
515 # gRPC handles serialization and deserialization, so we just need
516 # to pass in the functions for each.
517 if "run_aggregation_query" not in self._stubs:
518 self._stubs["run_aggregation_query"] = self.grpc_channel.unary_stream(
519 "/google.firestore.v1.Firestore/RunAggregationQuery",
520 request_serializer=firestore.RunAggregationQueryRequest.serialize,
521 response_deserializer=firestore.RunAggregationQueryResponse.deserialize,
522 )
523 return self._stubs["run_aggregation_query"]
524
525 @property
526 def partition_query(
527 self,
528 ) -> Callable[[firestore.PartitionQueryRequest], firestore.PartitionQueryResponse]:
529 r"""Return a callable for the partition query method over gRPC.
530
531 Partitions a query by returning partition cursors
532 that can be used to run the query in parallel. The
533 returned partition cursors are split points that can be
534 used by RunQuery as starting/end points for the query
535 results.
536
537 Returns:
538 Callable[[~.PartitionQueryRequest],
539 ~.PartitionQueryResponse]:
540 A function that, when called, will call the underlying RPC
541 on the server.
542 """
543 # Generate a "stub function" on-the-fly which will actually make
544 # the request.
545 # gRPC handles serialization and deserialization, so we just need
546 # to pass in the functions for each.
547 if "partition_query" not in self._stubs:
548 self._stubs["partition_query"] = self.grpc_channel.unary_unary(
549 "/google.firestore.v1.Firestore/PartitionQuery",
550 request_serializer=firestore.PartitionQueryRequest.serialize,
551 response_deserializer=firestore.PartitionQueryResponse.deserialize,
552 )
553 return self._stubs["partition_query"]
554
555 @property
556 def write(self) -> Callable[[firestore.WriteRequest], firestore.WriteResponse]:
557 r"""Return a callable for the write method over gRPC.
558
559 Streams batches of document updates and deletes, in
560 order. This method is only available via gRPC or
561 WebChannel (not REST).
562
563 Returns:
564 Callable[[~.WriteRequest],
565 ~.WriteResponse]:
566 A function that, when called, will call the underlying RPC
567 on the server.
568 """
569 # Generate a "stub function" on-the-fly which will actually make
570 # the request.
571 # gRPC handles serialization and deserialization, so we just need
572 # to pass in the functions for each.
573 if "write" not in self._stubs:
574 self._stubs["write"] = self.grpc_channel.stream_stream(
575 "/google.firestore.v1.Firestore/Write",
576 request_serializer=firestore.WriteRequest.serialize,
577 response_deserializer=firestore.WriteResponse.deserialize,
578 )
579 return self._stubs["write"]
580
581 @property
582 def listen(self) -> Callable[[firestore.ListenRequest], firestore.ListenResponse]:
583 r"""Return a callable for the listen method over gRPC.
584
585 Listens to changes. This method is only available via
586 gRPC or WebChannel (not REST).
587
588 Returns:
589 Callable[[~.ListenRequest],
590 ~.ListenResponse]:
591 A function that, when called, will call the underlying RPC
592 on the server.
593 """
594 # Generate a "stub function" on-the-fly which will actually make
595 # the request.
596 # gRPC handles serialization and deserialization, so we just need
597 # to pass in the functions for each.
598 if "listen" not in self._stubs:
599 self._stubs["listen"] = self.grpc_channel.stream_stream(
600 "/google.firestore.v1.Firestore/Listen",
601 request_serializer=firestore.ListenRequest.serialize,
602 response_deserializer=firestore.ListenResponse.deserialize,
603 )
604 return self._stubs["listen"]
605
606 @property
607 def list_collection_ids(
608 self,
609 ) -> Callable[
610 [firestore.ListCollectionIdsRequest], firestore.ListCollectionIdsResponse
611 ]:
612 r"""Return a callable for the list collection ids method over gRPC.
613
614 Lists all the collection IDs underneath a document.
615
616 Returns:
617 Callable[[~.ListCollectionIdsRequest],
618 ~.ListCollectionIdsResponse]:
619 A function that, when called, will call the underlying RPC
620 on the server.
621 """
622 # Generate a "stub function" on-the-fly which will actually make
623 # the request.
624 # gRPC handles serialization and deserialization, so we just need
625 # to pass in the functions for each.
626 if "list_collection_ids" not in self._stubs:
627 self._stubs["list_collection_ids"] = self.grpc_channel.unary_unary(
628 "/google.firestore.v1.Firestore/ListCollectionIds",
629 request_serializer=firestore.ListCollectionIdsRequest.serialize,
630 response_deserializer=firestore.ListCollectionIdsResponse.deserialize,
631 )
632 return self._stubs["list_collection_ids"]
633
634 @property
635 def batch_write(
636 self,
637 ) -> Callable[[firestore.BatchWriteRequest], firestore.BatchWriteResponse]:
638 r"""Return a callable for the batch write method over gRPC.
639
640 Applies a batch of write operations.
641
642 The BatchWrite method does not apply the write operations
643 atomically and can apply them out of order. Method does not
644 allow more than one write per document. Each write succeeds or
645 fails independently. See the
646 [BatchWriteResponse][google.firestore.v1.BatchWriteResponse] for
647 the success status of each write.
648
649 If you require an atomically applied set of writes, use
650 [Commit][google.firestore.v1.Firestore.Commit] instead.
651
652 Returns:
653 Callable[[~.BatchWriteRequest],
654 ~.BatchWriteResponse]:
655 A function that, when called, will call the underlying RPC
656 on the server.
657 """
658 # Generate a "stub function" on-the-fly which will actually make
659 # the request.
660 # gRPC handles serialization and deserialization, so we just need
661 # to pass in the functions for each.
662 if "batch_write" not in self._stubs:
663 self._stubs["batch_write"] = self.grpc_channel.unary_unary(
664 "/google.firestore.v1.Firestore/BatchWrite",
665 request_serializer=firestore.BatchWriteRequest.serialize,
666 response_deserializer=firestore.BatchWriteResponse.deserialize,
667 )
668 return self._stubs["batch_write"]
669
670 @property
671 def create_document(
672 self,
673 ) -> Callable[[firestore.CreateDocumentRequest], document.Document]:
674 r"""Return a callable for the create document method over gRPC.
675
676 Creates a new document.
677
678 Returns:
679 Callable[[~.CreateDocumentRequest],
680 ~.Document]:
681 A function that, when called, will call the underlying RPC
682 on the server.
683 """
684 # Generate a "stub function" on-the-fly which will actually make
685 # the request.
686 # gRPC handles serialization and deserialization, so we just need
687 # to pass in the functions for each.
688 if "create_document" not in self._stubs:
689 self._stubs["create_document"] = self.grpc_channel.unary_unary(
690 "/google.firestore.v1.Firestore/CreateDocument",
691 request_serializer=firestore.CreateDocumentRequest.serialize,
692 response_deserializer=document.Document.deserialize,
693 )
694 return self._stubs["create_document"]
695
696 def close(self):
697 self.grpc_channel.close()
698
699 @property
700 def delete_operation(
701 self,
702 ) -> Callable[[operations_pb2.DeleteOperationRequest], None]:
703 r"""Return a callable for the delete_operation method over gRPC."""
704 # Generate a "stub function" on-the-fly which will actually make
705 # the request.
706 # gRPC handles serialization and deserialization, so we just need
707 # to pass in the functions for each.
708 if "delete_operation" not in self._stubs:
709 self._stubs["delete_operation"] = self.grpc_channel.unary_unary(
710 "/google.longrunning.Operations/DeleteOperation",
711 request_serializer=operations_pb2.DeleteOperationRequest.SerializeToString,
712 response_deserializer=None,
713 )
714 return self._stubs["delete_operation"]
715
716 @property
717 def cancel_operation(
718 self,
719 ) -> Callable[[operations_pb2.CancelOperationRequest], None]:
720 r"""Return a callable for the cancel_operation method over gRPC."""
721 # Generate a "stub function" on-the-fly which will actually make
722 # the request.
723 # gRPC handles serialization and deserialization, so we just need
724 # to pass in the functions for each.
725 if "cancel_operation" not in self._stubs:
726 self._stubs["cancel_operation"] = self.grpc_channel.unary_unary(
727 "/google.longrunning.Operations/CancelOperation",
728 request_serializer=operations_pb2.CancelOperationRequest.SerializeToString,
729 response_deserializer=None,
730 )
731 return self._stubs["cancel_operation"]
732
733 @property
734 def get_operation(
735 self,
736 ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]:
737 r"""Return a callable for the get_operation method over gRPC."""
738 # Generate a "stub function" on-the-fly which will actually make
739 # the request.
740 # gRPC handles serialization and deserialization, so we just need
741 # to pass in the functions for each.
742 if "get_operation" not in self._stubs:
743 self._stubs["get_operation"] = self.grpc_channel.unary_unary(
744 "/google.longrunning.Operations/GetOperation",
745 request_serializer=operations_pb2.GetOperationRequest.SerializeToString,
746 response_deserializer=operations_pb2.Operation.FromString,
747 )
748 return self._stubs["get_operation"]
749
750 @property
751 def list_operations(
752 self,
753 ) -> Callable[
754 [operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse
755 ]:
756 r"""Return a callable for the list_operations method over gRPC."""
757 # Generate a "stub function" on-the-fly which will actually make
758 # the request.
759 # gRPC handles serialization and deserialization, so we just need
760 # to pass in the functions for each.
761 if "list_operations" not in self._stubs:
762 self._stubs["list_operations"] = self.grpc_channel.unary_unary(
763 "/google.longrunning.Operations/ListOperations",
764 request_serializer=operations_pb2.ListOperationsRequest.SerializeToString,
765 response_deserializer=operations_pb2.ListOperationsResponse.FromString,
766 )
767 return self._stubs["list_operations"]
768
769 @property
770 def kind(self) -> str:
771 return "grpc"
772
773
774__all__ = ("FirestoreGrpcTransport",)