| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- from __future__ import annotations
- __all__ = ["Headers", "RequestContext"]
- import time
- from typing import TYPE_CHECKING, Generic, TypeVar
- from ._headers import Headers
- if TYPE_CHECKING:
- from .method import MethodInfo
- REQ = TypeVar("REQ")
- RES = TypeVar("RES")
- class RequestContext(Generic[REQ, RES]):
- """Additional context for an RPC request message."""
- _method: MethodInfo[REQ, RES]
- _http_method: str
- _request_headers: Headers
- _response_headers: Headers | None
- _response_trailers: Headers | None
- def __init__(
- self,
- *,
- method: MethodInfo[REQ, RES],
- http_method: str,
- request_headers: Headers,
- timeout_ms: int | None = None,
- server_address: str | None = None,
- client_address: str | None = None,
- ) -> None:
- """
- Initialize a Context object.
- """
- self._method = method
- self._http_method = http_method
- self._request_headers = request_headers
- self._response_headers = None
- self._response_trailers = None
- self._server_address = server_address
- self._client_address = client_address
- if timeout_ms is None:
- self._end_time = None
- else:
- self._end_time = time.monotonic() + (timeout_ms / 1000.0)
- @property
- def method(self) -> MethodInfo[REQ, RES]:
- """Returns information about the RPC method being invoked."""
- return self._method
- @property
- def http_method(self) -> str:
- """Returns the HTTP method for this request.
- This is nearly always POST, but side-effect-free unary RPCs could be made
- via GET.
- """
- return self._http_method
- @property
- def request_headers(self) -> Headers:
- """Returns the request headers associated with the context."""
- return self._request_headers
- @property
- def response_headers(self) -> Headers:
- """
- Returns the response headers that will be sent before the response.
- """
- if self._response_headers is None:
- self._response_headers = Headers()
- return self._response_headers
- @property
- def response_trailers(self) -> Headers:
- """
- Returns the response trailers that will be sent after the response.
- """
- if self._response_trailers is None:
- self._response_trailers = Headers()
- return self._response_trailers
- @property
- def timeout_ms(self) -> float | None:
- """Returns the remaining time until the timeout in milliseconds, or None if no timeout is set."""
- if self._end_time is None:
- return None
- return (self._end_time - time.monotonic()) * 1000.0
- @property
- def server_address(self) -> str | None:
- """
- Returns the server address for this request, if available, as a "address:port" string.
- - On the client, this is components from the URL configured when constructing the client.
- - On the server, this is determined from the Host header and scheme of the request.
- """
- return self._server_address
- @property
- def client_address(self) -> str | None:
- """
- Returns the client address for this request, if available, as a "address:port" string.
- - On the client, this is never populated.
- - On the server, this is the value provided by the server implementation, generally
- the IP address and ephemeral port of the client.
- """
- return self._client_address
|