Skip to content

Validate Transport Support For Bidirectional Streaming#717

Open
jonathan343 wants to merge 1 commit into
developfrom
bidi-validation
Open

Validate Transport Support For Bidirectional Streaming#717
jonathan343 wants to merge 1 commit into
developfrom
bidi-validation

Conversation

@jonathan343

Copy link
Copy Markdown
Contributor

Overview

Problem

Only the AWS CRT HTTP client can perform true bidirectional (duplex) streaming in the Python ecosystem, since interleaving request and response data in practice requires HTTP/2. Code generation already defaults services with event streams to AWSCRTHTTPClient, but nothing stops a user from overriding config.transport with AIOHTTPClient or a custom transport that can't do this. When they then invoke a bidirectional operation, the request is sent and the stream appears to hang until it eventually dies with an error such as: smithy_core.exceptions.SmithyError: Server disconnected

Nothing in that error points at the actual problem (the configured transport), so this is painful to debug.

Solution

This PR makes duplex support an explicit, opt-in transport capability. A new SUPPORTS_DUPLEX_STREAMING class attribute on ClientTransport defaults to False, and RequestPipeline.duplex_stream now fails fast with an actionable UnsupportedTransportError before any request work happens. AWSCRTHTTPClient declares support, AIOHTTPClient explicitly does not (it buffers the full response before returning and aiohttp has no HTTP/2 support).

Example

Invoking a bidirectional operation with a non-duplex transport, with this PR:

config = Config(transport=AIOHTTPClient())
stream = await client.streaming_operation(input=..., config=config)

Without this PR: the request is sent, the stream stalls, and eventually fails mid-stream with SmithyError: Server disconnected.

With this PR: the call fails immediately, before anything is sent:

smithy_core.exceptions.UnsupportedTransportError: The configured transport (AIOHTTPClient) does not support duplex (bidirectional) event streaming, which is required by the com.example#StreamingOperation operation. Use a transport that does, such as smithy_http.aio.crt.AWSCRTHTTPClient. Custom transports that support duplex streaming must set SUPPORTS_DUPLEX_STREAMING to True.

Why opt-in rather than opt-out? A survey of the Python HTTP client landscape shows most clients cannot interleave request and response data, so absence of a declaration is treated as "not supported". The pipeline reads the attribute with getattr(transport, "SUPPORTS_DUPLEX_STREAMING", False), so existing custom transports that predate the attribute keep working for everything except duplex operations, which were already broken for them.

Why fail at call time instead of client construction? A non-duplex transport is perfectly valid for every other operation on the same client. The capability is only required when a duplex operation is actually invoked, so that is where validation happens.


By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Most Python HTTP clients cannot read response data while the request
body is still being written, so bidirectional event stream operations
fail mid-stream with an opaque connection error. Transports must now
opt in by setting SUPPORTS_DUPLEX_STREAMING to True, and
RequestPipeline.duplex_stream fails fast with UnsupportedTransportError
when the configured transport does not declare support.

AWSCRTHTTPClient and MockHTTPClient declare support; AIOHTTPClient
explicitly does not.
@jonathan343 jonathan343 requested a review from a team as a code owner June 12, 2026 03:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant