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