_server_shared.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. from __future__ import annotations
  2. from dataclasses import dataclass
  3. from typing import TYPE_CHECKING, Generic, TypeVar
  4. if TYPE_CHECKING:
  5. from collections.abc import AsyncIterator, Awaitable, Callable, Iterator
  6. from .method import MethodInfo
  7. from .request import RequestContext
  8. REQ = TypeVar("REQ")
  9. RES = TypeVar("RES")
  10. T = TypeVar("T")
  11. U = TypeVar("U")
  12. @dataclass(kw_only=True, frozen=True, slots=True)
  13. class Endpoint(Generic[REQ, RES]):
  14. """
  15. Represents an endpoint in a service.
  16. Attributes:
  17. method: The method to map to the RPC function.
  18. """
  19. method: MethodInfo[REQ, RES]
  20. @staticmethod
  21. def unary(
  22. method: MethodInfo[T, U],
  23. function: Callable[[T, RequestContext[T, U]], Awaitable[U]],
  24. ) -> EndpointUnary[T, U]:
  25. return EndpointUnary(method=method, function=function)
  26. @staticmethod
  27. def client_stream(
  28. method: MethodInfo[T, U],
  29. function: Callable[[AsyncIterator[T], RequestContext[T, U]], Awaitable[U]],
  30. ) -> EndpointClientStream[T, U]:
  31. return EndpointClientStream(method=method, function=function)
  32. @staticmethod
  33. def server_stream(
  34. method: MethodInfo[T, U],
  35. function: Callable[[T, RequestContext[T, U]], AsyncIterator[U]],
  36. ) -> EndpointServerStream[T, U]:
  37. return EndpointServerStream(method=method, function=function)
  38. @staticmethod
  39. def bidi_stream(
  40. method: MethodInfo[T, U],
  41. function: Callable[[AsyncIterator[T], RequestContext[T, U]], AsyncIterator[U]],
  42. ) -> EndpointBidiStream[T, U]:
  43. return EndpointBidiStream(method=method, function=function)
  44. @dataclass(kw_only=True, frozen=True, slots=True)
  45. class EndpointUnary(Endpoint[REQ, RES]):
  46. function: Callable[[REQ, RequestContext[REQ, RES]], Awaitable[RES]]
  47. @dataclass(kw_only=True, frozen=True, slots=True)
  48. class EndpointClientStream(Endpoint[REQ, RES]):
  49. function: Callable[[AsyncIterator[REQ], RequestContext[REQ, RES]], Awaitable[RES]]
  50. @dataclass(kw_only=True, frozen=True, slots=True)
  51. class EndpointServerStream(Endpoint[REQ, RES]):
  52. function: Callable[[REQ, RequestContext[REQ, RES]], AsyncIterator[RES]]
  53. @dataclass(kw_only=True, frozen=True, slots=True)
  54. class EndpointBidiStream(Endpoint[REQ, RES]):
  55. function: Callable[
  56. [AsyncIterator[REQ], RequestContext[REQ, RES]], AsyncIterator[RES]
  57. ]
  58. @dataclass(kw_only=True, frozen=True, slots=True)
  59. class EndpointSync(Generic[REQ, RES]):
  60. """
  61. Represents a sync endpoint in a service.
  62. Attributes:
  63. method: The method to map to the RPC function.
  64. """
  65. method: MethodInfo[REQ, RES]
  66. @staticmethod
  67. def unary(
  68. *, method: MethodInfo[T, U], function: Callable[[T, RequestContext[T, U]], U]
  69. ) -> EndpointUnarySync[T, U]:
  70. return EndpointUnarySync(method=method, function=function)
  71. @staticmethod
  72. def client_stream(
  73. *,
  74. method: MethodInfo[T, U],
  75. function: Callable[[Iterator[T], RequestContext[T, U]], U],
  76. ) -> EndpointClientStreamSync[T, U]:
  77. return EndpointClientStreamSync(method=method, function=function)
  78. @staticmethod
  79. def server_stream(
  80. *,
  81. method: MethodInfo[T, U],
  82. function: Callable[[T, RequestContext[T, U]], Iterator[U]],
  83. ) -> EndpointServerStreamSync[T, U]:
  84. return EndpointServerStreamSync(method=method, function=function)
  85. @staticmethod
  86. def bidi_stream(
  87. method: MethodInfo[T, U],
  88. function: Callable[[Iterator[T], RequestContext[T, U]], Iterator[U]],
  89. ) -> EndpointBidiStreamSync[T, U]:
  90. return EndpointBidiStreamSync(method=method, function=function)
  91. @dataclass(kw_only=True, frozen=True, slots=True)
  92. class EndpointUnarySync(EndpointSync[REQ, RES]):
  93. function: Callable[[REQ, RequestContext[REQ, RES]], RES]
  94. @dataclass(kw_only=True, frozen=True, slots=True)
  95. class EndpointClientStreamSync(EndpointSync[REQ, RES]):
  96. function: Callable[[Iterator[REQ], RequestContext[REQ, RES]], RES]
  97. @dataclass(kw_only=True, frozen=True, slots=True)
  98. class EndpointServerStreamSync(EndpointSync[REQ, RES]):
  99. function: Callable[[REQ, RequestContext[REQ, RES]], Iterator[RES]]
  100. @dataclass(kw_only=True, frozen=True, slots=True)
  101. class EndpointBidiStreamSync(EndpointSync[REQ, RES]):
  102. function: Callable[[Iterator[REQ], RequestContext[REQ, RES]], Iterator[RES]]