httpx.RequestNotRead: Attempted to access request content, without having called `read()`

See original GitHub issue

I would like to test if a client uses the REST interface in a proper way. I wanted to use respx to mock the HTTP requests. I found no easy way to test the content of the HTTP request sent to the service.

What I would expect:

  • I can use the content attribute on the Request object returned by the calls to verify correctness of the request.

What happens:

  • Accessing the content attribute throws an httpx.RequestNotRead exception
  • The workaround I have found is to access the stream._body attribute which is kind of a hack. Or maybe I don not use the library in a proper way and the documentation should show this kind of example.

Used Environment:

  • Python 3.8.5
  • pytest 6.0.2
  • httpx 0.15.5
  • respx 0.13.0

Here the minimal example code:

import json
import respx
import httpx


def my_client():
    httpx.post("http://www.example.com/entries", content=json.dumps({"id": "1234567"}))
    return True


@respx.mock
def test_rest_call():
    """If the client sends the correct HTTP request - url and content."""
    respx.post(
        "http://www.example.com/entries",
        alias="example",
    )
    my_client()
    assert respx.aliases["example"].called
    assert respx.aliases["example"].call_count == 1
    request,_ = respx.aliases["example"].calls[0]
    
    # This works but is kinda ugly
    assert request.stream._body == '{"id": "1234567"}'.encode()
    # Would expect to work, but throws exception 'httpx.RequestNotRead'
    assert request.content == '{"id": "1234567"}'.encode()

Calling this with pytest:

$ pytest tests/test_request.py 
============================================================ test session starts =============================================================
platform linux -- Python 3.8.5, pytest-6.0.2, py-1.9.0, pluggy-0.13.1
rootdir: /home/max/work/iov42/python/core-sdk-python
plugins: xdoctest-0.15.0, typeguard-2.9.1
collected 1 item                                                                                                                             

tests/test_request.py F                                                                                                                [100%]

================================================================== FAILURES ==================================================================
_______________________________________________________________ test_rest_call _______________________________________________________________

    @respx.mock
    def test_rest_call():
        respx.post(
            "http://www.example.com/entries",
            alias="example",
        )
        my_client()
        assert respx.aliases["example"].called
        assert respx.aliases["example"].call_count == 1
        request,_ = respx.aliases["example"].calls[0]
    
        # This works but is kinda ugly
        assert request.stream._body == '{"id": "1234567"}'.encode()
        # Would expect to work, but does not work
>       assert request.content == '{"id": "1234567"}'.encode()

tests/test_request.py:26: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <Request('POST', 'http://www.example.com/entries')>

    @property
    def content(self) -> bytes:
        if not hasattr(self, "_content"):
>           raise RequestNotRead()
E           httpx.RequestNotRead: Attempted to access request content, without having called `read()`.

/home/max/.cache/pypoetry/virtualenvs/iov42-core-python-4oIM64sE-py3.8/lib/python3.8/site-packages/httpx/_models.py:823: RequestNotRead
========================================================== short test summary info ===========================================================
FAILED tests/test_request.py::test_rest_call - httpx.RequestNotRead: Attempted to access request content, without having called `read()`.
============================================================= 1 failed in 0.17s ==============================================================

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
max-iov42commented, Oct 2, 2020

Yes, I meant matching the RequestPattern with content. And I agree with you, supporting both would be nice.

You have just to be careful, to not overwhelm users of respx with a plethora of parameters. That’s why I find respx “feels better” compared to pytest_httpx.

0reactions
lundbergcommented, Nov 12, 2020

FYI @max-iov42, #106 adds support for content pattern matching, etc. 😉

Read more comments on GitHub >

github_iconTop Results From Across the Web

Exceptions - HTTPX
Attempted to access streaming response content, without having called read() . class httpx.RequestNotRead (). Attempted to access streaming request content, ...
Read more >
httpx/_exceptions.py at master · encode/httpx - GitHub
super().__init__(message). class RequestNotRead(StreamError):. """ Attempted to access streaming request content, without having called `read()`.
Read more >
How to use the httpx.exceptions.HTTPError function in ... - Snyk
The developer made an error in accessing the request stream in an invalid way. """ class StreamConsumed(StreamError): """ Attempted to read or stream...
Read more >
Class Hierarchy
Class Hierarchy · httpx.RequestNotRead - Attempted to access streaming request content, without having called read() . · httpx.ResponseNotRead - ...
Read more >
python - httpx AsyncClient -missing method prepare_request
One could use httpx.Request class to write an prepare_request factory. import httpx def prepare_request(method, url, **kwargs): # a very ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found