Summary
PaymentTransport currently rejects an async-generator request body before it sends the initial request. As a result, wrapping a normal endpoint that returns 200 turns an otherwise valid streaming upload into PaymentError, even though the payment retry path is never entered.
Reproduction
Use PaymentTransport(methods=[], inner=httpx.MockTransport(...)) with a POST request whose content is an async generator. Have the inner transport read the body and return 200. On current main, handle_async_request raises:
Streaming request bodies (async generators) are not supported through the payment retry flow.
The inner transport is not called.
Expected behavior
A non-replayable stream should be allowed to make its initial request. If that response is not 402, the response should pass through unchanged. If the initial response is 402, the transport should still reject the paid retry because it cannot safely replay the body.
Proposed scope
Keep the existing buffering and replay behavior for bytes, form data, and multipart bodies. For an async-generator body, defer the unsupported-stream error until after the initial response is known to be 402.
Regression coverage
- async-generator
POST plus 200: the inner transport receives the full body and the caller receives 200;
- async-generator
POST plus 402: exactly one request is sent and the retry remains rejected;
- existing buffered-body retry tests remain unchanged.
This appears to be a narrow follow-up to #166. I can prepare the regression test and minimal patch if this behavior is desired.
Summary
PaymentTransportcurrently rejects an async-generator request body before it sends the initial request. As a result, wrapping a normal endpoint that returns200turns an otherwise valid streaming upload intoPaymentError, even though the payment retry path is never entered.Reproduction
Use
PaymentTransport(methods=[], inner=httpx.MockTransport(...))with aPOSTrequest whosecontentis an async generator. Have the inner transport read the body and return200. On currentmain,handle_async_requestraises:Streaming request bodies (async generators) are not supported through the payment retry flow.The inner transport is not called.
Expected behavior
A non-replayable stream should be allowed to make its initial request. If that response is not
402, the response should pass through unchanged. If the initial response is402, the transport should still reject the paid retry because it cannot safely replay the body.Proposed scope
Keep the existing buffering and replay behavior for bytes, form data, and multipart bodies. For an async-generator body, defer the unsupported-stream error until after the initial response is known to be
402.Regression coverage
POSTplus200: the inner transport receives the full body and the caller receives200;POSTplus402: exactly one request is sent and the retry remains rejected;This appears to be a narrow follow-up to #166. I can prepare the regression test and minimal patch if this behavior is desired.