Skip to content

Commit 4cc6a07

Browse files
committed
address comments
1 parent 5eafa15 commit 4cc6a07

File tree

4 files changed

+44
-31
lines changed

4 files changed

+44
-31
lines changed

packages/smithy-aws-core/src/smithy_aws_core/protocols/restjson.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def id(self) -> ShapeID:
1919
return self._id
2020

2121
@property
22-
def codec(self) -> Codec:
22+
def payload_codec(self) -> Codec:
2323
return self._codec
2424

2525
@property

packages/smithy-aws-core/src/smithy_aws_core/traits.py

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,29 @@
1616

1717
@dataclass(init=False, frozen=True)
1818
class RestJson1Trait(Trait, id=ShapeID("aws.protocols#restJson1")):
19-
http: set[str] = field(repr=False, hash=False, compare=False, default_factory=set)
20-
eventStreamHttp: set[str] = field(
21-
repr=False, hash=False, compare=False, default_factory=set
19+
http: Sequence[str] = field(
20+
repr=False, hash=False, compare=False, default_factory=tuple
21+
)
22+
event_stream_http: Sequence[str] = field(
23+
repr=False, hash=False, compare=False, default_factory=tuple
2224
)
2325

2426
def __init__(self, value: DocumentValue | DynamicTrait = None):
2527
super().__init__(value)
2628
assert isinstance(self.document_value, Mapping)
2729

28-
assert isinstance(self.document_value["http"], Sequence)
29-
for val in self.document_value["http"]:
30+
http_versions = self.document_value["http"]
31+
assert isinstance(http_versions, Sequence)
32+
for val in http_versions:
3033
assert isinstance(val, str)
31-
self.http.add(val)
32-
33-
if vals := self.document_value.get("eventStreamHttp") is None:
34-
object.__setattr__(self, "eventStreamHttp", self.http)
34+
object.__setattr__(self, "http", tuple(http_versions))
35+
event_stream_http_versions = self.document_value.get("eventStreamHttp")
36+
if not event_stream_http_versions:
37+
object.__setattr__(self, "event_stream_http", self.http)
3538
else:
36-
# check that eventStreamHttp is a subset of http
37-
assert isinstance(vals, Sequence)
38-
for val in self.document_value["eventStreamHttp"]:
39-
assert val in self.http
39+
assert isinstance(event_stream_http_versions, Sequence)
40+
for val in event_stream_http_versions:
4041
assert isinstance(val, str)
41-
self.eventStreamHttp.add(val)
42+
object.__setattr__(
43+
self, "event_stream_http", tuple(event_stream_http_versions)
44+
)

packages/smithy-core/src/smithy_core/protocols.py

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from smithy_core.codecs import Codec
77
from smithy_core.deserializers import DeserializeableShape
88
from smithy_core.documents import TypeRegistry
9+
from smithy_core.exceptions import ExpectationNotMetException
910
from smithy_core.interfaces import Endpoint, TypedProperties, URI
1011
from smithy_core.schemas import APIOperation
1112
from smithy_core.serializers import SerializeableShape
@@ -43,8 +44,8 @@ class HttpBindingClientProtocol(HttpClientProtocol):
4344
"""An HTTP-based protocol that uses HTTP binding traits."""
4445

4546
@property
46-
def codec(self) -> Codec:
47-
"""The codec used for the serde of input and output shapes."""
47+
def payload_codec(self) -> Codec:
48+
"""The codec used for the serde of input and output payloads."""
4849
...
4950

5051
@property
@@ -63,20 +64,23 @@ def serialize_request[
6364
endpoint: URI,
6465
context: TypedProperties,
6566
) -> HTTPRequest:
66-
# TODO: request binding cache like done in SJ
67+
# TODO(optimization): request binding cache like done in SJ
6768
serializer = HTTPRequestSerializer(
68-
payload_codec=self.codec,
69-
http_trait=operation.schema.expect_trait(HTTPTrait), # TODO
69+
payload_codec=self.payload_codec,
70+
http_trait=operation.schema.expect_trait(HTTPTrait),
7071
endpoint_trait=operation.schema.get_trait(EndpointTrait),
7172
)
7273

73-
input.serialize(serializer=serializer)
74+
input.serialize(
75+
serializer=serializer
76+
) # TODO: ensure serializer adds content-type
7477
request = serializer.result
7578

7679
if request is None:
77-
raise ValueError("Request is None") # TODO
80+
raise ExpectationNotMetException(
81+
"Expected request to be serialized, but was None"
82+
)
7883

79-
request.fields["content-type"].add(self.content_type)
8084
return request
8185

8286
async def deserialize_response[
@@ -96,15 +100,17 @@ async def deserialize_response[
96100
raise NotImplementedError
97101

98102
body = response.body
99-
# TODO: extract to utility, seems common
100-
if (read := getattr(body, "read", None)) is not None and iscoroutinefunction(
101-
read
102-
):
103-
body = BytesIO(await read())
104103

105-
# TODO: response binding cache like done in SJ
104+
# if body is not streaming and is async, we have to buffer it
105+
if not operation.output_stream_member:
106+
if (
107+
read := getattr(body, "read", None)
108+
) is not None and iscoroutinefunction(read):
109+
body = BytesIO(await read())
110+
111+
# TODO(optimization): response binding cache like done in SJ
106112
deserializer = HTTPResponseDeserializer(
107-
payload_codec=self.codec,
113+
payload_codec=self.payload_codec,
108114
http_trait=operation.schema.expect_trait(HTTPTrait),
109115
response=response,
110116
body=body, # type: ignore

packages/smithy-http/src/smithy_http/serializers.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,10 @@ def begin_struct(self, schema: Schema) -> Iterator[ShapeSerializer]:
112112
) is not None and not iscoroutinefunction(seek):
113113
seek(0)
114114

115+
# TODO: conditional on empty-ness and a param of the protocol?
116+
headers = binding_serializer.header_serializer.headers
117+
headers.append(("content-type", self._payload_codec.media_type))
118+
115119
self.result = _HTTPRequest(
116120
method=self._http_trait.method,
117121
destination=URI(
@@ -122,7 +126,7 @@ def begin_struct(self, schema: Schema) -> Iterator[ShapeSerializer]:
122126
prefix=self._http_trait.query or "",
123127
),
124128
),
125-
fields=tuples_to_fields(binding_serializer.header_serializer.headers),
129+
fields=tuples_to_fields(headers),
126130
body=payload,
127131
)
128132

0 commit comments

Comments
 (0)