Skip to content

Commit 0955d19

Browse files
Vishwa Prakash Gayasenmeta-codesync[bot]
authored andcommitted
Add ThriftBidiType for metadata
Summary: - Add metadata type for Bidi - Bidi has 3 fields: firstResponse, streamType & sinkType - Fix thrift python metadata API accordingly Reviewed By: sazonovkirill, tlj77 Differential Revision: D88336249 fbshipit-source-id: 3d2b5ae37776f4b282a8e8aadc353af01e253585
1 parent a7017d1 commit 0955d19

4 files changed

Lines changed: 107 additions & 0 deletions

File tree

third-party/thrift/src/thrift/lib/python/metadata.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from typing import cast, Iterator, Mapping, Optional, Sequence, Tuple, Type, Union
2323

2424
from apache.thrift.metadata.thrift_types import (
25+
ThriftBidiType,
2526
ThriftConstStruct,
2627
ThriftConstValue,
2728
ThriftEnum,
@@ -59,6 +60,7 @@ class ThriftKind(enum.Enum):
5960
TYPEDEF = 7
6061
STREAM = 8
6162
SINK = 9
63+
BIDI = 10
6264

6365

6466
class ThriftConstKind(enum.Enum):
@@ -80,6 +82,7 @@ class ThriftConstKind(enum.Enum):
8082
ThriftMapType,
8183
ThriftTypedefType,
8284
ThriftSinkType,
85+
ThriftBidiType,
8386
ThriftStreamType,
8487
]
8588

@@ -103,6 +106,7 @@ def __init__(
103106
ThriftSetType,
104107
ThriftMapType,
105108
ThriftTypedefType,
109+
ThriftBidiType,
106110
ThriftSinkType,
107111
ThriftStreamType,
108112
),
@@ -165,6 +169,10 @@ def _fbthrift_create(
165169
val = thriftType.value
166170
assert isinstance(val, ThriftSinkType)
167171
return ThriftSinkProxy(val, thriftMeta)
172+
elif thriftType.type is ThriftType.Type.t_bidi:
173+
val = thriftType.value
174+
assert isinstance(val, ThriftBidiType)
175+
return ThriftBidiProxy(val, thriftMeta)
168176
val = thriftType.value
169177
assert isinstance(val, ThriftPrimitiveType)
170178
specialType = ThriftTypeProxy(val, thriftMeta)
@@ -221,6 +229,11 @@ def as_sink(self) -> "ThriftSinkProxy":
221229
return cast(ThriftSinkProxy, self)
222230
raise TypeError("Type is not a sink")
223231

232+
def as_bidi(self) -> "ThriftBidiProxy":
233+
if self.kind == ThriftKind.BIDI:
234+
return cast(ThriftBidiProxy, self)
235+
raise TypeError("Type is not a bidirectional stream")
236+
224237

225238
class ThriftSetProxy(ThriftTypeProxy):
226239
valueType: ThriftTypeProxy
@@ -313,6 +326,26 @@ def __init__(
313326
)
314327

315328

329+
class ThriftBidiProxy(ThriftTypeProxy):
330+
streamElemType: ThriftTypeProxy
331+
sinkElemType: ThriftTypeProxy
332+
initialResponseType: ThriftTypeProxy
333+
334+
def __init__(self, thriftType: ThriftBidiType, thriftMeta: ThriftMetadata) -> None:
335+
super().__init__(thriftType, thriftMeta)
336+
self.kind: ThriftKind = ThriftKind.BIDI
337+
self.streamElemType = ThriftTypeProxy._fbthrift_create(
338+
thriftType.streamElemType, self.thriftMeta
339+
)
340+
self.sinkElemType = ThriftTypeProxy._fbthrift_create(
341+
thriftType.sinkElemType, self.thriftMeta
342+
)
343+
if thriftType.initialResponseType is not None:
344+
self.initialResponseType = ThriftTypeProxy._fbthrift_create(
345+
thriftType.initialResponseType, self.thriftMeta
346+
)
347+
348+
316349
class ThriftFieldProxy:
317350
type: ThriftTypeProxy
318351
thriftType: ThriftField

third-party/thrift/src/thrift/lib/python/metadata.pyi

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ from typing import (
2828
)
2929

3030
from apache.thrift.metadata.thrift_types import (
31+
ThriftBidiType,
3132
ThriftConstStruct,
3233
ThriftConstValue,
3334
ThriftEnum,
@@ -67,6 +68,7 @@ class ThriftKind(Enum):
6768
TYPEDEF: ThriftKind = ...
6869
STREAM: ThriftKind = ...
6970
SINK: ThriftKind = ...
71+
BIDI: ThriftKind = ...
7072

7173
class ThriftConstKind(Enum):
7274
CV_BOOL: ThriftConstKind = ...
@@ -90,6 +92,7 @@ class ThriftTypeProxy:
9092
ThriftEnum,
9193
ThriftStruct,
9294
ThriftSinkType,
95+
ThriftBidiType,
9396
ThriftStreamType,
9497
]
9598
thriftMeta: ThriftMetadata
@@ -104,6 +107,7 @@ class ThriftTypeProxy:
104107
def as_typedef(self) -> ThriftTypedefProxy: ...
105108
def as_stream(self) -> ThriftStreamProxy: ...
106109
def as_sink(self) -> ThriftSinkProxy: ...
110+
def as_bidi(self) -> ThriftBidiProxy: ...
107111

108112
class ThriftSetProxy(ThriftTypeProxy):
109113
thriftType: ThriftSetType
@@ -134,6 +138,11 @@ class ThriftStreamProxy(ThriftTypeProxy):
134138
elemType: ThriftTypeProxy
135139
initialResponseType: Optional[ThriftTypeProxy]
136140

141+
class ThriftBidiProxy(ThriftTypeProxy):
142+
streamElemType: ThriftTypeProxy
143+
sinkElemType: ThriftTypeProxy
144+
initialResponseType: ThriftTypeProxy
145+
137146
class ThriftFieldProxy(Protocol):
138147
id: int
139148
name: str

third-party/thrift/src/thrift/lib/python/test/metadata.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
)
3333
from testing.thrift_services import TestingServiceInterface
3434
from testing.thrift_types import Complex, hard, HardError, mixed, NestedError, Perm
35+
from thrift.python.bidi_service.thrift_clients import TestBidiService
3536
from thrift.python.metadata import (
3637
gen_metadata,
3738
ThriftExceptionProxy,
@@ -344,3 +345,51 @@ def test_gen_metadata_with_module_returns_thrift_metadata(self) -> None:
344345
self.assertIsNotNone(meta.structs)
345346
self.assertIsNotNone(meta.services)
346347
self.assertIsNotNone(meta.exceptions)
348+
349+
def test_metadata_bidirectional_streaming(self) -> None:
350+
bidi_service = gen_metadata(TestBidiService)
351+
self.assertEqual(bidi_service.name, "bidi_service.TestBidiService")
352+
353+
# Get the echo function which has bidirectional streaming
354+
echo_func = None
355+
for func in bidi_service.functions:
356+
if func.name == "echo":
357+
echo_func = func
358+
break
359+
360+
self.assertIsNotNone(echo_func, "echo function should exist")
361+
362+
# Test that the return type is a bidirectional stream
363+
bidi_type = echo_func.return_type.as_bidi()
364+
365+
# Verify stream element type is string
366+
self.assertEqual(
367+
bidi_type.streamElemType.as_primitive(),
368+
ThriftPrimitiveType.THRIFT_STRING_TYPE,
369+
)
370+
371+
# Verify sink element type is string
372+
self.assertEqual(
373+
bidi_type.sinkElemType.as_primitive(),
374+
ThriftPrimitiveType.THRIFT_STRING_TYPE,
375+
)
376+
377+
# Test echoWithResponse which has an initial response
378+
echo_with_response = None
379+
for func in bidi_service.functions:
380+
if func.name == "echoWithResponse":
381+
echo_with_response = func
382+
break
383+
384+
self.assertIsNotNone(
385+
echo_with_response, "echoWithResponse function should exist"
386+
)
387+
388+
bidi_with_response = echo_with_response.return_type.as_bidi()
389+
390+
# Verify it has an initial response type
391+
self.assertIsNotNone(bidi_with_response.initialResponseType)
392+
self.assertEqual(
393+
bidi_with_response.initialResponseType.as_primitive(),
394+
ThriftPrimitiveType.THRIFT_STRING_TYPE,
395+
)

third-party/thrift/src/thrift/lib/thrift/metadata.thrift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,21 @@ struct ThriftSinkType {
147147
3: optional ThriftType initialResponseType;
148148
}
149149

150+
struct ThriftBidiType {
151+
@java.Recursive
152+
@rust.Box
153+
@cpp.Ref{type = cpp.RefType.Unique}
154+
1: optional ThriftType initialResponseType;
155+
@java.Recursive
156+
@rust.Box
157+
@cpp.Ref{type = cpp.RefType.Unique}
158+
2: optional ThriftType streamElemType;
159+
@java.Recursive
160+
@rust.Box
161+
@cpp.Ref{type = cpp.RefType.Unique}
162+
3: optional ThriftType sinkElemType;
163+
}
164+
150165
@hack.MigrationBlockingLegacyJSONSerialization
151166
union ThriftType {
152167
1: ThriftPrimitiveType t_primitive;
@@ -159,6 +174,7 @@ union ThriftType {
159174
8: ThriftTypedefType t_typedef;
160175
9: ThriftStreamType t_stream;
161176
10: ThriftSinkType t_sink;
177+
11: ThriftBidiType t_bidi;
162178
}
163179

164180
struct ThriftEnum {

0 commit comments

Comments
 (0)