_client_adaptations.py 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015
  1. # Copyright 2016 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. """Translates gRPC's client-side API into gRPC's client-side Beta API."""
  15. import grpc
  16. from grpc import _common
  17. from grpc.beta import _metadata
  18. from grpc.beta import interfaces
  19. from grpc.framework.common import cardinality
  20. from grpc.framework.foundation import future
  21. from grpc.framework.interfaces.face import face
  22. # pylint: disable=too-many-arguments,too-many-locals,unused-argument
  23. _STATUS_CODE_TO_ABORTION_KIND_AND_ABORTION_ERROR_CLASS = {
  24. grpc.StatusCode.CANCELLED: (
  25. face.Abortion.Kind.CANCELLED,
  26. face.CancellationError,
  27. ),
  28. grpc.StatusCode.UNKNOWN: (
  29. face.Abortion.Kind.REMOTE_FAILURE,
  30. face.RemoteError,
  31. ),
  32. grpc.StatusCode.DEADLINE_EXCEEDED: (
  33. face.Abortion.Kind.EXPIRED,
  34. face.ExpirationError,
  35. ),
  36. grpc.StatusCode.UNIMPLEMENTED: (
  37. face.Abortion.Kind.LOCAL_FAILURE,
  38. face.LocalError,
  39. ),
  40. }
  41. def _effective_metadata(metadata, metadata_transformer):
  42. non_none_metadata = () if metadata is None else metadata
  43. if metadata_transformer is None:
  44. return non_none_metadata
  45. else:
  46. return metadata_transformer(non_none_metadata)
  47. def _credentials(grpc_call_options):
  48. return None if grpc_call_options is None else grpc_call_options.credentials
  49. def _abortion(rpc_error_call):
  50. code = rpc_error_call.code()
  51. pair = _STATUS_CODE_TO_ABORTION_KIND_AND_ABORTION_ERROR_CLASS.get(code)
  52. error_kind = face.Abortion.Kind.LOCAL_FAILURE if pair is None else pair[0]
  53. return face.Abortion(
  54. error_kind,
  55. rpc_error_call.initial_metadata(),
  56. rpc_error_call.trailing_metadata(),
  57. code,
  58. rpc_error_call.details(),
  59. )
  60. def _abortion_error(rpc_error_call):
  61. code = rpc_error_call.code()
  62. pair = _STATUS_CODE_TO_ABORTION_KIND_AND_ABORTION_ERROR_CLASS.get(code)
  63. exception_class = face.AbortionError if pair is None else pair[1]
  64. return exception_class(
  65. rpc_error_call.initial_metadata(),
  66. rpc_error_call.trailing_metadata(),
  67. code,
  68. rpc_error_call.details(),
  69. )
  70. class _InvocationProtocolContext(interfaces.GRPCInvocationContext):
  71. def disable_next_request_compression(self):
  72. pass # TODO(https://github.com/grpc/grpc/issues/4078): design, implement.
  73. class _Rendezvous(future.Future, face.Call):
  74. def __init__(self, response_future, response_iterator, call):
  75. self._future = response_future
  76. self._iterator = response_iterator
  77. self._call = call
  78. def cancel(self):
  79. return self._call.cancel()
  80. def cancelled(self):
  81. return self._future.cancelled()
  82. def running(self):
  83. return self._future.running()
  84. def done(self):
  85. return self._future.done()
  86. def result(self, timeout=None):
  87. try:
  88. return self._future.result(timeout=timeout)
  89. except grpc.RpcError as rpc_error_call:
  90. raise _abortion_error(rpc_error_call)
  91. except grpc.FutureTimeoutError:
  92. raise future.TimeoutError()
  93. except grpc.FutureCancelledError:
  94. raise future.CancelledError()
  95. def exception(self, timeout=None):
  96. try:
  97. rpc_error_call = self._future.exception(timeout=timeout)
  98. if rpc_error_call is None:
  99. return None
  100. else:
  101. return _abortion_error(rpc_error_call)
  102. except grpc.FutureTimeoutError:
  103. raise future.TimeoutError()
  104. except grpc.FutureCancelledError:
  105. raise future.CancelledError()
  106. def traceback(self, timeout=None):
  107. try:
  108. return self._future.traceback(timeout=timeout)
  109. except grpc.FutureTimeoutError:
  110. raise future.TimeoutError()
  111. except grpc.FutureCancelledError:
  112. raise future.CancelledError()
  113. def add_done_callback(self, fn):
  114. self._future.add_done_callback(lambda ignored_callback: fn(self))
  115. def __iter__(self):
  116. return self
  117. def _next(self):
  118. try:
  119. return next(self._iterator)
  120. except grpc.RpcError as rpc_error_call:
  121. raise _abortion_error(rpc_error_call)
  122. def __next__(self):
  123. return self._next()
  124. def next(self):
  125. return self._next()
  126. def is_active(self):
  127. return self._call.is_active()
  128. def time_remaining(self):
  129. return self._call.time_remaining()
  130. def add_abortion_callback(self, abortion_callback):
  131. def done_callback():
  132. if self.code() is not grpc.StatusCode.OK:
  133. abortion_callback(_abortion(self._call))
  134. registered = self._call.add_callback(done_callback)
  135. return None if registered else done_callback()
  136. def protocol_context(self):
  137. return _InvocationProtocolContext()
  138. def initial_metadata(self):
  139. return _metadata.beta(self._call.initial_metadata())
  140. def terminal_metadata(self):
  141. return _metadata.beta(self._call.terminal_metadata())
  142. def code(self):
  143. return self._call.code()
  144. def details(self):
  145. return self._call.details()
  146. def _blocking_unary_unary(
  147. channel,
  148. group,
  149. method,
  150. timeout,
  151. with_call,
  152. protocol_options,
  153. metadata,
  154. metadata_transformer,
  155. request,
  156. request_serializer,
  157. response_deserializer,
  158. ):
  159. try:
  160. multi_callable = channel.unary_unary(
  161. _common.fully_qualified_method(group, method),
  162. request_serializer=request_serializer,
  163. response_deserializer=response_deserializer,
  164. )
  165. effective_metadata = _effective_metadata(metadata, metadata_transformer)
  166. if with_call:
  167. response, call = multi_callable.with_call(
  168. request,
  169. timeout=timeout,
  170. metadata=_metadata.unbeta(effective_metadata),
  171. credentials=_credentials(protocol_options),
  172. )
  173. return response, _Rendezvous(None, None, call)
  174. else:
  175. return multi_callable(
  176. request,
  177. timeout=timeout,
  178. metadata=_metadata.unbeta(effective_metadata),
  179. credentials=_credentials(protocol_options),
  180. )
  181. except grpc.RpcError as rpc_error_call:
  182. raise _abortion_error(rpc_error_call)
  183. def _future_unary_unary(
  184. channel,
  185. group,
  186. method,
  187. timeout,
  188. protocol_options,
  189. metadata,
  190. metadata_transformer,
  191. request,
  192. request_serializer,
  193. response_deserializer,
  194. ):
  195. multi_callable = channel.unary_unary(
  196. _common.fully_qualified_method(group, method),
  197. request_serializer=request_serializer,
  198. response_deserializer=response_deserializer,
  199. )
  200. effective_metadata = _effective_metadata(metadata, metadata_transformer)
  201. response_future = multi_callable.future(
  202. request,
  203. timeout=timeout,
  204. metadata=_metadata.unbeta(effective_metadata),
  205. credentials=_credentials(protocol_options),
  206. )
  207. return _Rendezvous(response_future, None, response_future)
  208. def _unary_stream(
  209. channel,
  210. group,
  211. method,
  212. timeout,
  213. protocol_options,
  214. metadata,
  215. metadata_transformer,
  216. request,
  217. request_serializer,
  218. response_deserializer,
  219. ):
  220. multi_callable = channel.unary_stream(
  221. _common.fully_qualified_method(group, method),
  222. request_serializer=request_serializer,
  223. response_deserializer=response_deserializer,
  224. )
  225. effective_metadata = _effective_metadata(metadata, metadata_transformer)
  226. response_iterator = multi_callable(
  227. request,
  228. timeout=timeout,
  229. metadata=_metadata.unbeta(effective_metadata),
  230. credentials=_credentials(protocol_options),
  231. )
  232. return _Rendezvous(None, response_iterator, response_iterator)
  233. def _blocking_stream_unary(
  234. channel,
  235. group,
  236. method,
  237. timeout,
  238. with_call,
  239. protocol_options,
  240. metadata,
  241. metadata_transformer,
  242. request_iterator,
  243. request_serializer,
  244. response_deserializer,
  245. ):
  246. try:
  247. multi_callable = channel.stream_unary(
  248. _common.fully_qualified_method(group, method),
  249. request_serializer=request_serializer,
  250. response_deserializer=response_deserializer,
  251. )
  252. effective_metadata = _effective_metadata(metadata, metadata_transformer)
  253. if with_call:
  254. response, call = multi_callable.with_call(
  255. request_iterator,
  256. timeout=timeout,
  257. metadata=_metadata.unbeta(effective_metadata),
  258. credentials=_credentials(protocol_options),
  259. )
  260. return response, _Rendezvous(None, None, call)
  261. else:
  262. return multi_callable(
  263. request_iterator,
  264. timeout=timeout,
  265. metadata=_metadata.unbeta(effective_metadata),
  266. credentials=_credentials(protocol_options),
  267. )
  268. except grpc.RpcError as rpc_error_call:
  269. raise _abortion_error(rpc_error_call)
  270. def _future_stream_unary(
  271. channel,
  272. group,
  273. method,
  274. timeout,
  275. protocol_options,
  276. metadata,
  277. metadata_transformer,
  278. request_iterator,
  279. request_serializer,
  280. response_deserializer,
  281. ):
  282. multi_callable = channel.stream_unary(
  283. _common.fully_qualified_method(group, method),
  284. request_serializer=request_serializer,
  285. response_deserializer=response_deserializer,
  286. )
  287. effective_metadata = _effective_metadata(metadata, metadata_transformer)
  288. response_future = multi_callable.future(
  289. request_iterator,
  290. timeout=timeout,
  291. metadata=_metadata.unbeta(effective_metadata),
  292. credentials=_credentials(protocol_options),
  293. )
  294. return _Rendezvous(response_future, None, response_future)
  295. def _stream_stream(
  296. channel,
  297. group,
  298. method,
  299. timeout,
  300. protocol_options,
  301. metadata,
  302. metadata_transformer,
  303. request_iterator,
  304. request_serializer,
  305. response_deserializer,
  306. ):
  307. multi_callable = channel.stream_stream(
  308. _common.fully_qualified_method(group, method),
  309. request_serializer=request_serializer,
  310. response_deserializer=response_deserializer,
  311. )
  312. effective_metadata = _effective_metadata(metadata, metadata_transformer)
  313. response_iterator = multi_callable(
  314. request_iterator,
  315. timeout=timeout,
  316. metadata=_metadata.unbeta(effective_metadata),
  317. credentials=_credentials(protocol_options),
  318. )
  319. return _Rendezvous(None, response_iterator, response_iterator)
  320. class _UnaryUnaryMultiCallable(face.UnaryUnaryMultiCallable):
  321. def __init__(
  322. self,
  323. channel,
  324. group,
  325. method,
  326. metadata_transformer,
  327. request_serializer,
  328. response_deserializer,
  329. ):
  330. self._channel = channel
  331. self._group = group
  332. self._method = method
  333. self._metadata_transformer = metadata_transformer
  334. self._request_serializer = request_serializer
  335. self._response_deserializer = response_deserializer
  336. def __call__(
  337. self,
  338. request,
  339. timeout,
  340. metadata=None,
  341. with_call=False,
  342. protocol_options=None,
  343. ):
  344. return _blocking_unary_unary(
  345. self._channel,
  346. self._group,
  347. self._method,
  348. timeout,
  349. with_call,
  350. protocol_options,
  351. metadata,
  352. self._metadata_transformer,
  353. request,
  354. self._request_serializer,
  355. self._response_deserializer,
  356. )
  357. def future(self, request, timeout, metadata=None, protocol_options=None):
  358. return _future_unary_unary(
  359. self._channel,
  360. self._group,
  361. self._method,
  362. timeout,
  363. protocol_options,
  364. metadata,
  365. self._metadata_transformer,
  366. request,
  367. self._request_serializer,
  368. self._response_deserializer,
  369. )
  370. def event(
  371. self,
  372. request,
  373. receiver,
  374. abortion_callback,
  375. timeout,
  376. metadata=None,
  377. protocol_options=None,
  378. ):
  379. raise NotImplementedError()
  380. class _UnaryStreamMultiCallable(face.UnaryStreamMultiCallable):
  381. def __init__(
  382. self,
  383. channel,
  384. group,
  385. method,
  386. metadata_transformer,
  387. request_serializer,
  388. response_deserializer,
  389. ):
  390. self._channel = channel
  391. self._group = group
  392. self._method = method
  393. self._metadata_transformer = metadata_transformer
  394. self._request_serializer = request_serializer
  395. self._response_deserializer = response_deserializer
  396. def __call__(self, request, timeout, metadata=None, protocol_options=None):
  397. return _unary_stream(
  398. self._channel,
  399. self._group,
  400. self._method,
  401. timeout,
  402. protocol_options,
  403. metadata,
  404. self._metadata_transformer,
  405. request,
  406. self._request_serializer,
  407. self._response_deserializer,
  408. )
  409. def event(
  410. self,
  411. request,
  412. receiver,
  413. abortion_callback,
  414. timeout,
  415. metadata=None,
  416. protocol_options=None,
  417. ):
  418. raise NotImplementedError()
  419. class _StreamUnaryMultiCallable(face.StreamUnaryMultiCallable):
  420. def __init__(
  421. self,
  422. channel,
  423. group,
  424. method,
  425. metadata_transformer,
  426. request_serializer,
  427. response_deserializer,
  428. ):
  429. self._channel = channel
  430. self._group = group
  431. self._method = method
  432. self._metadata_transformer = metadata_transformer
  433. self._request_serializer = request_serializer
  434. self._response_deserializer = response_deserializer
  435. def __call__(
  436. self,
  437. request_iterator,
  438. timeout,
  439. metadata=None,
  440. with_call=False,
  441. protocol_options=None,
  442. ):
  443. return _blocking_stream_unary(
  444. self._channel,
  445. self._group,
  446. self._method,
  447. timeout,
  448. with_call,
  449. protocol_options,
  450. metadata,
  451. self._metadata_transformer,
  452. request_iterator,
  453. self._request_serializer,
  454. self._response_deserializer,
  455. )
  456. def future(
  457. self, request_iterator, timeout, metadata=None, protocol_options=None
  458. ):
  459. return _future_stream_unary(
  460. self._channel,
  461. self._group,
  462. self._method,
  463. timeout,
  464. protocol_options,
  465. metadata,
  466. self._metadata_transformer,
  467. request_iterator,
  468. self._request_serializer,
  469. self._response_deserializer,
  470. )
  471. def event(
  472. self,
  473. receiver,
  474. abortion_callback,
  475. timeout,
  476. metadata=None,
  477. protocol_options=None,
  478. ):
  479. raise NotImplementedError()
  480. class _StreamStreamMultiCallable(face.StreamStreamMultiCallable):
  481. def __init__(
  482. self,
  483. channel,
  484. group,
  485. method,
  486. metadata_transformer,
  487. request_serializer,
  488. response_deserializer,
  489. ):
  490. self._channel = channel
  491. self._group = group
  492. self._method = method
  493. self._metadata_transformer = metadata_transformer
  494. self._request_serializer = request_serializer
  495. self._response_deserializer = response_deserializer
  496. def __call__(
  497. self, request_iterator, timeout, metadata=None, protocol_options=None
  498. ):
  499. return _stream_stream(
  500. self._channel,
  501. self._group,
  502. self._method,
  503. timeout,
  504. protocol_options,
  505. metadata,
  506. self._metadata_transformer,
  507. request_iterator,
  508. self._request_serializer,
  509. self._response_deserializer,
  510. )
  511. def event(
  512. self,
  513. receiver,
  514. abortion_callback,
  515. timeout,
  516. metadata=None,
  517. protocol_options=None,
  518. ):
  519. raise NotImplementedError()
  520. class _GenericStub(face.GenericStub):
  521. def __init__(
  522. self,
  523. channel,
  524. metadata_transformer,
  525. request_serializers,
  526. response_deserializers,
  527. ):
  528. self._channel = channel
  529. self._metadata_transformer = metadata_transformer
  530. self._request_serializers = request_serializers or {}
  531. self._response_deserializers = response_deserializers or {}
  532. def blocking_unary_unary(
  533. self,
  534. group,
  535. method,
  536. request,
  537. timeout,
  538. metadata=None,
  539. with_call=None,
  540. protocol_options=None,
  541. ):
  542. request_serializer = self._request_serializers.get(
  543. (
  544. group,
  545. method,
  546. )
  547. )
  548. response_deserializer = self._response_deserializers.get(
  549. (
  550. group,
  551. method,
  552. )
  553. )
  554. return _blocking_unary_unary(
  555. self._channel,
  556. group,
  557. method,
  558. timeout,
  559. with_call,
  560. protocol_options,
  561. metadata,
  562. self._metadata_transformer,
  563. request,
  564. request_serializer,
  565. response_deserializer,
  566. )
  567. def future_unary_unary(
  568. self,
  569. group,
  570. method,
  571. request,
  572. timeout,
  573. metadata=None,
  574. protocol_options=None,
  575. ):
  576. request_serializer = self._request_serializers.get(
  577. (
  578. group,
  579. method,
  580. )
  581. )
  582. response_deserializer = self._response_deserializers.get(
  583. (
  584. group,
  585. method,
  586. )
  587. )
  588. return _future_unary_unary(
  589. self._channel,
  590. group,
  591. method,
  592. timeout,
  593. protocol_options,
  594. metadata,
  595. self._metadata_transformer,
  596. request,
  597. request_serializer,
  598. response_deserializer,
  599. )
  600. def inline_unary_stream(
  601. self,
  602. group,
  603. method,
  604. request,
  605. timeout,
  606. metadata=None,
  607. protocol_options=None,
  608. ):
  609. request_serializer = self._request_serializers.get(
  610. (
  611. group,
  612. method,
  613. )
  614. )
  615. response_deserializer = self._response_deserializers.get(
  616. (
  617. group,
  618. method,
  619. )
  620. )
  621. return _unary_stream(
  622. self._channel,
  623. group,
  624. method,
  625. timeout,
  626. protocol_options,
  627. metadata,
  628. self._metadata_transformer,
  629. request,
  630. request_serializer,
  631. response_deserializer,
  632. )
  633. def blocking_stream_unary(
  634. self,
  635. group,
  636. method,
  637. request_iterator,
  638. timeout,
  639. metadata=None,
  640. with_call=None,
  641. protocol_options=None,
  642. ):
  643. request_serializer = self._request_serializers.get(
  644. (
  645. group,
  646. method,
  647. )
  648. )
  649. response_deserializer = self._response_deserializers.get(
  650. (
  651. group,
  652. method,
  653. )
  654. )
  655. return _blocking_stream_unary(
  656. self._channel,
  657. group,
  658. method,
  659. timeout,
  660. with_call,
  661. protocol_options,
  662. metadata,
  663. self._metadata_transformer,
  664. request_iterator,
  665. request_serializer,
  666. response_deserializer,
  667. )
  668. def future_stream_unary(
  669. self,
  670. group,
  671. method,
  672. request_iterator,
  673. timeout,
  674. metadata=None,
  675. protocol_options=None,
  676. ):
  677. request_serializer = self._request_serializers.get(
  678. (
  679. group,
  680. method,
  681. )
  682. )
  683. response_deserializer = self._response_deserializers.get(
  684. (
  685. group,
  686. method,
  687. )
  688. )
  689. return _future_stream_unary(
  690. self._channel,
  691. group,
  692. method,
  693. timeout,
  694. protocol_options,
  695. metadata,
  696. self._metadata_transformer,
  697. request_iterator,
  698. request_serializer,
  699. response_deserializer,
  700. )
  701. def inline_stream_stream(
  702. self,
  703. group,
  704. method,
  705. request_iterator,
  706. timeout,
  707. metadata=None,
  708. protocol_options=None,
  709. ):
  710. request_serializer = self._request_serializers.get(
  711. (
  712. group,
  713. method,
  714. )
  715. )
  716. response_deserializer = self._response_deserializers.get(
  717. (
  718. group,
  719. method,
  720. )
  721. )
  722. return _stream_stream(
  723. self._channel,
  724. group,
  725. method,
  726. timeout,
  727. protocol_options,
  728. metadata,
  729. self._metadata_transformer,
  730. request_iterator,
  731. request_serializer,
  732. response_deserializer,
  733. )
  734. def event_unary_unary(
  735. self,
  736. group,
  737. method,
  738. request,
  739. receiver,
  740. abortion_callback,
  741. timeout,
  742. metadata=None,
  743. protocol_options=None,
  744. ):
  745. raise NotImplementedError()
  746. def event_unary_stream(
  747. self,
  748. group,
  749. method,
  750. request,
  751. receiver,
  752. abortion_callback,
  753. timeout,
  754. metadata=None,
  755. protocol_options=None,
  756. ):
  757. raise NotImplementedError()
  758. def event_stream_unary(
  759. self,
  760. group,
  761. method,
  762. receiver,
  763. abortion_callback,
  764. timeout,
  765. metadata=None,
  766. protocol_options=None,
  767. ):
  768. raise NotImplementedError()
  769. def event_stream_stream(
  770. self,
  771. group,
  772. method,
  773. receiver,
  774. abortion_callback,
  775. timeout,
  776. metadata=None,
  777. protocol_options=None,
  778. ):
  779. raise NotImplementedError()
  780. def unary_unary(self, group, method):
  781. request_serializer = self._request_serializers.get(
  782. (
  783. group,
  784. method,
  785. )
  786. )
  787. response_deserializer = self._response_deserializers.get(
  788. (
  789. group,
  790. method,
  791. )
  792. )
  793. return _UnaryUnaryMultiCallable(
  794. self._channel,
  795. group,
  796. method,
  797. self._metadata_transformer,
  798. request_serializer,
  799. response_deserializer,
  800. )
  801. def unary_stream(self, group, method):
  802. request_serializer = self._request_serializers.get(
  803. (
  804. group,
  805. method,
  806. )
  807. )
  808. response_deserializer = self._response_deserializers.get(
  809. (
  810. group,
  811. method,
  812. )
  813. )
  814. return _UnaryStreamMultiCallable(
  815. self._channel,
  816. group,
  817. method,
  818. self._metadata_transformer,
  819. request_serializer,
  820. response_deserializer,
  821. )
  822. def stream_unary(self, group, method):
  823. request_serializer = self._request_serializers.get(
  824. (
  825. group,
  826. method,
  827. )
  828. )
  829. response_deserializer = self._response_deserializers.get(
  830. (
  831. group,
  832. method,
  833. )
  834. )
  835. return _StreamUnaryMultiCallable(
  836. self._channel,
  837. group,
  838. method,
  839. self._metadata_transformer,
  840. request_serializer,
  841. response_deserializer,
  842. )
  843. def stream_stream(self, group, method):
  844. request_serializer = self._request_serializers.get(
  845. (
  846. group,
  847. method,
  848. )
  849. )
  850. response_deserializer = self._response_deserializers.get(
  851. (
  852. group,
  853. method,
  854. )
  855. )
  856. return _StreamStreamMultiCallable(
  857. self._channel,
  858. group,
  859. method,
  860. self._metadata_transformer,
  861. request_serializer,
  862. response_deserializer,
  863. )
  864. def __enter__(self):
  865. return self
  866. def __exit__(self, exc_type, exc_val, exc_tb):
  867. return False
  868. class _DynamicStub(face.DynamicStub):
  869. def __init__(self, backing_generic_stub, group, cardinalities):
  870. self._generic_stub = backing_generic_stub
  871. self._group = group
  872. self._cardinalities = cardinalities
  873. def __getattr__(self, attr):
  874. method_cardinality = self._cardinalities.get(attr)
  875. if method_cardinality is cardinality.Cardinality.UNARY_UNARY:
  876. return self._generic_stub.unary_unary(self._group, attr)
  877. elif method_cardinality is cardinality.Cardinality.UNARY_STREAM:
  878. return self._generic_stub.unary_stream(self._group, attr)
  879. elif method_cardinality is cardinality.Cardinality.STREAM_UNARY:
  880. return self._generic_stub.stream_unary(self._group, attr)
  881. elif method_cardinality is cardinality.Cardinality.STREAM_STREAM:
  882. return self._generic_stub.stream_stream(self._group, attr)
  883. else:
  884. raise AttributeError(
  885. '_DynamicStub object has no attribute "%s"!' % attr
  886. )
  887. def __enter__(self):
  888. return self
  889. def __exit__(self, exc_type, exc_val, exc_tb):
  890. return False
  891. def generic_stub(
  892. channel,
  893. host,
  894. metadata_transformer,
  895. request_serializers,
  896. response_deserializers,
  897. ):
  898. return _GenericStub(
  899. channel,
  900. metadata_transformer,
  901. request_serializers,
  902. response_deserializers,
  903. )
  904. def dynamic_stub(
  905. channel,
  906. service,
  907. cardinalities,
  908. host,
  909. metadata_transformer,
  910. request_serializers,
  911. response_deserializers,
  912. ):
  913. return _DynamicStub(
  914. _GenericStub(
  915. channel,
  916. metadata_transformer,
  917. request_serializers,
  918. response_deserializers,
  919. ),
  920. service,
  921. cardinalities,
  922. )