responses icon indicating copy to clipboard operation
responses copied to clipboard

IO object used in requests data

Open Zhong-Zendesk opened this issue 1 year ago • 1 comments

Describe the bug

I have an edge case where I had to use BytesIO as the data for requests, in production environment, the IO is consumed after the first request, and all subsequent requests read '' as a result. I wanted to reproduce this behavior/issue in tests (for regression tests). However, there seems to be no way to reproduce this behavior.

Additional context

No response

Version of responses

0.25.3

Steps to Reproduce

# reproduction_test.py
import io

import pytest_responses
import requests


def bad_io():
    data = io.BytesIO(b"some binary data")
    first = requests.post("https://httpbin.org/post", data=data)
    last = requests.post("https://httpbin.org/post", data=data)
    return first, last

def test_with_responses(responses):
    responses.add(responses.POST, "https://httpbin.org/post")
    bad_io()
    assert responses.calls[0].request.body.getvalue() == b"some binary data"
    assert responses.calls[1].request.body.getvalue() == b""

if __name__ == "__main__":
    import pprint
    first_repsonse, last_response = bad_io()
   

    pprint.pprint(first_repsonse.json()["data"])
    pprint.pprint(last_response.json()["data"])

compare the difference in body/data between python reproduction_test.py vs pytest reproduction_test.py

Expected Result

Test passes - the IO object is read/consumed after the first request The second request body is ``

Actual Result

Test fails. The second request got the same payload as the initial request.

Zhong-Zendesk avatar Dec 12 '24 22:12 Zhong-Zendesk

Currently responses will read and buffer any IO streams that are passed to it, which is why you're not able to reproduce the scenario you're looking to emulate. I don't have a good idea on how we could support both buffered IO objects and un-buffered ones.

markstory avatar Dec 13 '24 14:12 markstory