smithy-http 0.4.2__tar.gz → 0.4.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. smithy_http-0.4.3/.changes/0.4.3.json +12 -0
  2. {smithy_http-0.4.2 → smithy_http-0.4.3}/CHANGELOG.md +8 -0
  3. {smithy_http-0.4.2 → smithy_http-0.4.3}/PKG-INFO +1 -1
  4. {smithy_http-0.4.2 → smithy_http-0.4.3}/src/smithy_http/__init__.py +1 -1
  5. {smithy_http-0.4.2 → smithy_http-0.4.3}/src/smithy_http/aio/aiohttp.py +20 -2
  6. {smithy_http-0.4.2 → smithy_http-0.4.3}/src/smithy_http/aio/crt.py +0 -1
  7. {smithy_http-0.4.2 → smithy_http-0.4.3}/src/smithy_http/aio/protocols.py +23 -2
  8. {smithy_http-0.4.2 → smithy_http-0.4.3}/.changes/0.0.1.json +0 -0
  9. {smithy_http-0.4.2 → smithy_http-0.4.3}/.changes/0.1.0.json +0 -0
  10. {smithy_http-0.4.2 → smithy_http-0.4.3}/.changes/0.2.0.json +0 -0
  11. {smithy_http-0.4.2 → smithy_http-0.4.3}/.changes/0.2.1.json +0 -0
  12. {smithy_http-0.4.2 → smithy_http-0.4.3}/.changes/0.3.0.json +0 -0
  13. {smithy_http-0.4.2 → smithy_http-0.4.3}/.changes/0.3.1.json +0 -0
  14. {smithy_http-0.4.2 → smithy_http-0.4.3}/.changes/0.4.0.json +0 -0
  15. {smithy_http-0.4.2 → smithy_http-0.4.3}/.changes/0.4.1.json +0 -0
  16. {smithy_http-0.4.2 → smithy_http-0.4.3}/.changes/0.4.2.json +0 -0
  17. {smithy_http-0.4.2 → smithy_http-0.4.3}/.gitignore +0 -0
  18. {smithy_http-0.4.2 → smithy_http-0.4.3}/NOTICE +0 -0
  19. {smithy_http-0.4.2 → smithy_http-0.4.3}/README.md +0 -0
  20. {smithy_http-0.4.2 → smithy_http-0.4.3}/pyproject.toml +0 -0
  21. {smithy_http-0.4.2 → smithy_http-0.4.3}/src/smithy_http/aio/__init__.py +0 -0
  22. {smithy_http-0.4.2 → smithy_http-0.4.3}/src/smithy_http/aio/auth/__init__.py +0 -0
  23. {smithy_http-0.4.2 → smithy_http-0.4.3}/src/smithy_http/aio/auth/apikey.py +0 -0
  24. {smithy_http-0.4.2 → smithy_http-0.4.3}/src/smithy_http/aio/identity/__init__.py +0 -0
  25. {smithy_http-0.4.2 → smithy_http-0.4.3}/src/smithy_http/aio/identity/apikey.py +0 -0
  26. {smithy_http-0.4.2 → smithy_http-0.4.3}/src/smithy_http/aio/interfaces/__init__.py +0 -0
  27. {smithy_http-0.4.2 → smithy_http-0.4.3}/src/smithy_http/aio/restjson.py +0 -0
  28. {smithy_http-0.4.2 → smithy_http-0.4.3}/src/smithy_http/bindings.py +0 -0
  29. {smithy_http-0.4.2 → smithy_http-0.4.3}/src/smithy_http/deserializers.py +0 -0
  30. {smithy_http-0.4.2 → smithy_http-0.4.3}/src/smithy_http/endpoints.py +0 -0
  31. {smithy_http-0.4.2 → smithy_http-0.4.3}/src/smithy_http/exceptions.py +0 -0
  32. {smithy_http-0.4.2 → smithy_http-0.4.3}/src/smithy_http/interceptors/__init__.py +0 -0
  33. {smithy_http-0.4.2 → smithy_http-0.4.3}/src/smithy_http/interceptors/user_agent.py +0 -0
  34. {smithy_http-0.4.2 → smithy_http-0.4.3}/src/smithy_http/interfaces/__init__.py +0 -0
  35. {smithy_http-0.4.2 → smithy_http-0.4.3}/src/smithy_http/plugins/__init__.py +0 -0
  36. {smithy_http-0.4.2 → smithy_http-0.4.3}/src/smithy_http/py.typed +0 -0
  37. {smithy_http-0.4.2 → smithy_http-0.4.3}/src/smithy_http/restjson.py +0 -0
  38. {smithy_http-0.4.2 → smithy_http-0.4.3}/src/smithy_http/serializers.py +0 -0
  39. {smithy_http-0.4.2 → smithy_http-0.4.3}/src/smithy_http/testing/__init__.py +0 -0
  40. {smithy_http-0.4.2 → smithy_http-0.4.3}/src/smithy_http/testing/mockhttp.py +0 -0
  41. {smithy_http-0.4.2 → smithy_http-0.4.3}/src/smithy_http/testing/utils.py +0 -0
  42. {smithy_http-0.4.2 → smithy_http-0.4.3}/src/smithy_http/user_agent.py +0 -0
  43. {smithy_http-0.4.2 → smithy_http-0.4.3}/src/smithy_http/utils.py +0 -0
@@ -0,0 +1,12 @@
1
+ {
2
+ "changes": [
3
+ {
4
+ "type": "enhancement",
5
+ "description": "Enabled HTTP binding protocols to resolve modeled response errors when wire identifiers do not exactly match registered shape IDs. ([#742](https://github.com/smithy-lang/smithy-python/pull/742))"
6
+ },
7
+ {
8
+ "type": "bugfix",
9
+ "description": "Fixed `AIOHTTPClient` sending omitted request payloads with chunked transfer encoding."
10
+ }
11
+ ]
12
+ }
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.4.3
4
+
5
+ ### Enhancements
6
+ * Enabled HTTP binding protocols to resolve modeled response errors when wire identifiers do not exactly match registered shape IDs. ([#742](https://github.com/smithy-lang/smithy-python/pull/742))
7
+
8
+ ### Bug fixes
9
+ * Fixed `AIOHTTPClient` sending omitted request payloads with chunked transfer encoding.
10
+
3
11
  ## v0.4.2
4
12
 
5
13
  ### Bug fixes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: smithy-http
3
- Version: 0.4.2
3
+ Version: 0.4.3
4
4
  Summary: HTTP components for Smithy tooling.
5
5
  Project-URL: Changelog, https://github.com/smithy-lang/smithy-python/blob/develop/packages/smithy-http/CHANGELOG.md
6
6
  Project-URL: Code, https://github.com/smithy-lang/smithy-python/blob/develop/packages/smithy-http/
@@ -7,7 +7,7 @@ from typing import get_args
7
7
  from . import interfaces
8
8
  from .interfaces import FieldPosition
9
9
 
10
- __version__ = "0.4.2"
10
+ __version__ = "0.4.3"
11
11
 
12
12
  _VALID_FIELD_POSITIONS = frozenset(get_args(FieldPosition))
13
13
 
@@ -90,8 +90,13 @@ class AIOHTTPClient(HTTPClient):
90
90
  chain.from_iterable(fld.as_tuples() for fld in request.fields)
91
91
  )
92
92
 
93
- body: StreamingBlob = request.body
94
- if not isinstance(body, AsyncBytesReader):
93
+ body: StreamingBlob | None = request.body
94
+ if (
95
+ "content-length" not in request.fields
96
+ and "transfer-encoding" not in request.fields
97
+ ):
98
+ body = await self._prepare_body(body)
99
+ elif not isinstance(body, AsyncBytesReader):
95
100
  body = AsyncBytesReader(body)
96
101
 
97
102
  # The typing on `params` is incorrect, it'll happily accept a mapping whose
@@ -106,6 +111,19 @@ class AIOHTTPClient(HTTPClient):
106
111
  ) as resp:
107
112
  return await self._marshal_response(resp)
108
113
 
114
+ async def _prepare_body(self, body: StreamingBlob) -> AsyncBytesReader | None:
115
+ """Convert a body for aiohttp, omitting seekable bodies with no data."""
116
+ if not isinstance(body, AsyncBytesReader):
117
+ body = AsyncBytesReader(body)
118
+
119
+ if not body.seekable():
120
+ return body
121
+
122
+ position = await body.seek(0, 1)
123
+ end = await body.seek(0, 2)
124
+ await body.seek(position)
125
+ return None if position == end else body
126
+
109
127
  def _serialize_uri_without_query(self, uri: URI) -> yarl.URL:
110
128
  """Serialize all parts of the URI up to and including the path."""
111
129
  return yarl.URL.build(
@@ -1,7 +1,6 @@
1
1
  # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  # pyright: reportMissingTypeStubs=false,reportUnknownMemberType=false
4
- # flake8: noqa: F811
5
4
  from collections.abc import AsyncGenerator, AsyncIterable
6
5
  from copy import deepcopy
7
6
  from dataclasses import dataclass
@@ -23,6 +23,7 @@ from smithy_core.interfaces import StreamingBlob as SyncStreamingBlob
23
23
  from smithy_core.prelude import DOCUMENT
24
24
  from smithy_core.schemas import APIOperation
25
25
  from smithy_core.serializers import SerializeableShape
26
+ from smithy_core.shapes import ShapeID
26
27
  from smithy_core.traits import EndpointTrait, HTTPTrait
27
28
 
28
29
  from ..deserializers import HTTPResponseDeserializer
@@ -185,15 +186,26 @@ class HttpBindingClientProtocol(HttpClientProtocol):
185
186
  error_id = self.error_identifier.identify(
186
187
  operation=operation, response=response
187
188
  )
189
+ if error_id is not None and error_id not in error_registry:
190
+ error_id = self._resolve_error_id(
191
+ operation=operation,
192
+ error_id=error_id,
193
+ )
188
194
 
189
195
  if error_id is None and self._matches_content_type(response):
190
196
  if isinstance(response_body, bytearray):
191
197
  response_body = bytes(response_body)
192
198
  deserializer = self.payload_codec.create_deserializer(source=response_body)
193
199
  document = deserializer.read_document(schema=DOCUMENT)
200
+ document_error_id = document.discriminator
201
+ if document_error_id not in error_registry:
202
+ document_error_id = self._resolve_error_id(
203
+ operation=operation,
204
+ error_id=document_error_id,
205
+ )
194
206
 
195
- if document.discriminator in error_registry:
196
- error_id = document.discriminator
207
+ if document_error_id in error_registry:
208
+ error_id = document_error_id
197
209
  if isinstance(response_body, SeekableBytesReader):
198
210
  response_body.seek(0)
199
211
 
@@ -236,6 +248,15 @@ class HttpBindingClientProtocol(HttpClientProtocol):
236
248
  is_retry_safe=is_throttle or is_timeout or None,
237
249
  )
238
250
 
251
+ def _resolve_error_id(
252
+ self,
253
+ *,
254
+ operation: APIOperation[Any, Any],
255
+ error_id: ShapeID,
256
+ ) -> ShapeID:
257
+ """Resolve a response discriminator to its modeled error shape ID."""
258
+ return error_id
259
+
239
260
  def _matches_content_type(self, response: HTTPResponse) -> bool:
240
261
  if "content-type" not in response.fields:
241
262
  return False
File without changes
File without changes
File without changes
File without changes