• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2019 The gRPC Authors
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14"""Abstract base classes for client-side Call objects.
15
16Call objects represents the RPC itself, and offer methods to access / modify
17its information. They also offer methods to manipulate the life-cycle of the
18RPC, e.g. cancellation.
19"""
20
21from abc import ABCMeta
22from abc import abstractmethod
23from typing import Any, AsyncIterator, Generator, Generic, Optional, Union
24
25import grpc
26
27from ._metadata import Metadata
28from ._typing import DoneCallbackType
29from ._typing import EOFType
30from ._typing import RequestType
31from ._typing import ResponseType
32
33__all__ = "RpcContext", "Call", "UnaryUnaryCall", "UnaryStreamCall"
34
35
36class RpcContext(metaclass=ABCMeta):
37    """Provides RPC-related information and action."""
38
39    @abstractmethod
40    def cancelled(self) -> bool:
41        """Return True if the RPC is cancelled.
42
43        The RPC is cancelled when the cancellation was requested with cancel().
44
45        Returns:
46          A bool indicates whether the RPC is cancelled or not.
47        """
48
49    @abstractmethod
50    def done(self) -> bool:
51        """Return True if the RPC is done.
52
53        An RPC is done if the RPC is completed, cancelled or aborted.
54
55        Returns:
56          A bool indicates if the RPC is done.
57        """
58
59    @abstractmethod
60    def time_remaining(self) -> Optional[float]:
61        """Describes the length of allowed time remaining for the RPC.
62
63        Returns:
64          A nonnegative float indicating the length of allowed time in seconds
65          remaining for the RPC to complete before it is considered to have
66          timed out, or None if no deadline was specified for the RPC.
67        """
68
69    @abstractmethod
70    def cancel(self) -> bool:
71        """Cancels the RPC.
72
73        Idempotent and has no effect if the RPC has already terminated.
74
75        Returns:
76          A bool indicates if the cancellation is performed or not.
77        """
78
79    @abstractmethod
80    def add_done_callback(self, callback: DoneCallbackType) -> None:
81        """Registers a callback to be called on RPC termination.
82
83        Args:
84          callback: A callable object will be called with the call object as
85          its only argument.
86        """
87
88
89class Call(RpcContext, metaclass=ABCMeta):
90    """The abstract base class of an RPC on the client-side."""
91
92    @abstractmethod
93    async def initial_metadata(self) -> Metadata:
94        """Accesses the initial metadata sent by the server.
95
96        Returns:
97          The initial :term:`metadata`.
98        """
99
100    @abstractmethod
101    async def trailing_metadata(self) -> Metadata:
102        """Accesses the trailing metadata sent by the server.
103
104        Returns:
105          The trailing :term:`metadata`.
106        """
107
108    @abstractmethod
109    async def code(self) -> grpc.StatusCode:
110        """Accesses the status code sent by the server.
111
112        Returns:
113          The StatusCode value for the RPC.
114        """
115
116    @abstractmethod
117    async def details(self) -> str:
118        """Accesses the details sent by the server.
119
120        Returns:
121          The details string of the RPC.
122        """
123
124    @abstractmethod
125    async def wait_for_connection(self) -> None:
126        """Waits until connected to peer and raises aio.AioRpcError if failed.
127
128        This is an EXPERIMENTAL method.
129
130        This method ensures the RPC has been successfully connected. Otherwise,
131        an AioRpcError will be raised to explain the reason of the connection
132        failure.
133
134        This method is recommended for building retry mechanisms.
135        """
136
137
138class UnaryUnaryCall(
139    Generic[RequestType, ResponseType], Call, metaclass=ABCMeta
140):
141    """The abstract base class of an unary-unary RPC on the client-side."""
142
143    @abstractmethod
144    def __await__(self) -> Generator[Any, None, ResponseType]:
145        """Await the response message to be ready.
146
147        Returns:
148          The response message of the RPC.
149        """
150
151
152class UnaryStreamCall(
153    Generic[RequestType, ResponseType], Call, metaclass=ABCMeta
154):
155    @abstractmethod
156    def __aiter__(self) -> AsyncIterator[ResponseType]:
157        """Returns the async iterator representation that yields messages.
158
159        Under the hood, it is calling the "read" method.
160
161        Returns:
162          An async iterator object that yields messages.
163        """
164
165    @abstractmethod
166    async def read(self) -> Union[EOFType, ResponseType]:
167        """Reads one message from the stream.
168
169        Read operations must be serialized when called from multiple
170        coroutines.
171
172        Note that the iterator and read/write APIs may not be mixed on
173        a single RPC.
174
175        Returns:
176          A response message, or an `grpc.aio.EOF` to indicate the end of the
177          stream.
178        """
179
180
181class StreamUnaryCall(
182    Generic[RequestType, ResponseType], Call, metaclass=ABCMeta
183):
184    @abstractmethod
185    async def write(self, request: RequestType) -> None:
186        """Writes one message to the stream.
187
188        Note that the iterator and read/write APIs may not be mixed on
189        a single RPC.
190
191        Raises:
192          An RpcError exception if the write failed.
193        """
194
195    @abstractmethod
196    async def done_writing(self) -> None:
197        """Notifies server that the client is done sending messages.
198
199        After done_writing is called, any additional invocation to the write
200        function will fail. This function is idempotent.
201        """
202
203    @abstractmethod
204    def __await__(self) -> Generator[Any, None, ResponseType]:
205        """Await the response message to be ready.
206
207        Returns:
208          The response message of the stream.
209        """
210
211
212class StreamStreamCall(
213    Generic[RequestType, ResponseType], Call, metaclass=ABCMeta
214):
215    @abstractmethod
216    def __aiter__(self) -> AsyncIterator[ResponseType]:
217        """Returns the async iterator representation that yields messages.
218
219        Under the hood, it is calling the "read" method.
220
221        Returns:
222          An async iterator object that yields messages.
223        """
224
225    @abstractmethod
226    async def read(self) -> Union[EOFType, ResponseType]:
227        """Reads one message from the stream.
228
229        Read operations must be serialized when called from multiple
230        coroutines.
231
232        Note that the iterator and read/write APIs may not be mixed on
233        a single RPC.
234
235        Returns:
236          A response message, or an `grpc.aio.EOF` to indicate the end of the
237          stream.
238        """
239
240    @abstractmethod
241    async def write(self, request: RequestType) -> None:
242        """Writes one message to the stream.
243
244        Note that the iterator and read/write APIs may not be mixed on
245        a single RPC.
246
247        Raises:
248          An RpcError exception if the write failed.
249        """
250
251    @abstractmethod
252    async def done_writing(self) -> None:
253        """Notifies server that the client is done sending messages.
254
255        After done_writing is called, any additional invocation to the write
256        function will fail. This function is idempotent.
257        """
258