• 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, abstractmethod
22from typing import AsyncIterable, Awaitable, Generic, Optional, Union
23
24import grpc
25
26from ._typing import (DoneCallbackType, EOFType, RequestType, ResponseType)
27from ._metadata import Metadata
28
29__all__ = 'RpcContext', 'Call', 'UnaryUnaryCall', 'UnaryStreamCall'
30
31
32class RpcContext(metaclass=ABCMeta):
33    """Provides RPC-related information and action."""
34
35    @abstractmethod
36    def cancelled(self) -> bool:
37        """Return True if the RPC is cancelled.
38
39        The RPC is cancelled when the cancellation was requested with cancel().
40
41        Returns:
42          A bool indicates whether the RPC is cancelled or not.
43        """
44
45    @abstractmethod
46    def done(self) -> bool:
47        """Return True if the RPC is done.
48
49        An RPC is done if the RPC is completed, cancelled or aborted.
50
51        Returns:
52          A bool indicates if the RPC is done.
53        """
54
55    @abstractmethod
56    def time_remaining(self) -> Optional[float]:
57        """Describes the length of allowed time remaining for the RPC.
58
59        Returns:
60          A nonnegative float indicating the length of allowed time in seconds
61          remaining for the RPC to complete before it is considered to have
62          timed out, or None if no deadline was specified for the RPC.
63        """
64
65    @abstractmethod
66    def cancel(self) -> bool:
67        """Cancels the RPC.
68
69        Idempotent and has no effect if the RPC has already terminated.
70
71        Returns:
72          A bool indicates if the cancellation is performed or not.
73        """
74
75    @abstractmethod
76    def add_done_callback(self, callback: DoneCallbackType) -> None:
77        """Registers a callback to be called on RPC termination.
78
79        Args:
80          callback: A callable object will be called with the call object as
81          its only argument.
82        """
83
84
85class Call(RpcContext, metaclass=ABCMeta):
86    """The abstract base class of an RPC on the client-side."""
87
88    @abstractmethod
89    async def initial_metadata(self) -> Metadata:
90        """Accesses the initial metadata sent by the server.
91
92        Returns:
93          The initial :term:`metadata`.
94        """
95
96    @abstractmethod
97    async def trailing_metadata(self) -> Metadata:
98        """Accesses the trailing metadata sent by the server.
99
100        Returns:
101          The trailing :term:`metadata`.
102        """
103
104    @abstractmethod
105    async def code(self) -> grpc.StatusCode:
106        """Accesses the status code sent by the server.
107
108        Returns:
109          The StatusCode value for the RPC.
110        """
111
112    @abstractmethod
113    async def details(self) -> str:
114        """Accesses the details sent by the server.
115
116        Returns:
117          The details string of the RPC.
118        """
119
120    @abstractmethod
121    async def wait_for_connection(self) -> None:
122        """Waits until connected to peer and raises aio.AioRpcError if failed.
123
124        This is an EXPERIMENTAL method.
125
126        This method ensures the RPC has been successfully connected. Otherwise,
127        an AioRpcError will be raised to explain the reason of the connection
128        failure.
129
130        This method is recommended for building retry mechanisms.
131        """
132
133
134class UnaryUnaryCall(Generic[RequestType, ResponseType],
135                     Call,
136                     metaclass=ABCMeta):
137    """The abstract base class of an unary-unary RPC on the client-side."""
138
139    @abstractmethod
140    def __await__(self) -> Awaitable[ResponseType]:
141        """Await the response message to be ready.
142
143        Returns:
144          The response message of the RPC.
145        """
146
147
148class UnaryStreamCall(Generic[RequestType, ResponseType],
149                      Call,
150                      metaclass=ABCMeta):
151
152    @abstractmethod
153    def __aiter__(self) -> AsyncIterable[ResponseType]:
154        """Returns the async iterable representation that yields messages.
155
156        Under the hood, it is calling the "read" method.
157
158        Returns:
159          An async iterable object that yields messages.
160        """
161
162    @abstractmethod
163    async def read(self) -> Union[EOFType, ResponseType]:
164        """Reads one message from the stream.
165
166        Read operations must be serialized when called from multiple
167        coroutines.
168
169        Returns:
170          A response message, or an `grpc.aio.EOF` to indicate the end of the
171          stream.
172        """
173
174
175class StreamUnaryCall(Generic[RequestType, ResponseType],
176                      Call,
177                      metaclass=ABCMeta):
178
179    @abstractmethod
180    async def write(self, request: RequestType) -> None:
181        """Writes one message to the stream.
182
183        Raises:
184          An RpcError exception if the write failed.
185        """
186
187    @abstractmethod
188    async def done_writing(self) -> None:
189        """Notifies server that the client is done sending messages.
190
191        After done_writing is called, any additional invocation to the write
192        function will fail. This function is idempotent.
193        """
194
195    @abstractmethod
196    def __await__(self) -> Awaitable[ResponseType]:
197        """Await the response message to be ready.
198
199        Returns:
200          The response message of the stream.
201        """
202
203
204class StreamStreamCall(Generic[RequestType, ResponseType],
205                       Call,
206                       metaclass=ABCMeta):
207
208    @abstractmethod
209    def __aiter__(self) -> AsyncIterable[ResponseType]:
210        """Returns the async iterable representation that yields messages.
211
212        Under the hood, it is calling the "read" method.
213
214        Returns:
215          An async iterable object that yields messages.
216        """
217
218    @abstractmethod
219    async def read(self) -> Union[EOFType, ResponseType]:
220        """Reads one message from the stream.
221
222        Read operations must be serialized when called from multiple
223        coroutines.
224
225        Returns:
226          A response message, or an `grpc.aio.EOF` to indicate the end of the
227          stream.
228        """
229
230    @abstractmethod
231    async def write(self, request: RequestType) -> None:
232        """Writes one message to the stream.
233
234        Raises:
235          An RpcError exception if the write failed.
236        """
237
238    @abstractmethod
239    async def done_writing(self) -> None:
240        """Notifies server that the client is done sending messages.
241
242        After done_writing is called, any additional invocation to the write
243        function will fail. This function is idempotent.
244        """
245