Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to convert a dict object in requests.models.Response object in Python?

I am trying to test a function which contain an API call. So in the function I have this line of code :

api_request = dict(requests.get(url_of_the_API).json())

So I tried to use patch like this :

@patch('requests.get')
def test_products_list_creator(self, mock_get):
                
    mock_get.return_value = json.dumps({"products":
        {
            "name": "apple",
            "categories": "fruit,red"
        }
    })

But at the line of my API call, python throw me this error :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

AttributeError: 'str' object has no attribute 'json'

I tried to print type(requests.get(url_of_the_API}.json")) to know what it was and I got this : <class 'requests.models.Response'>

There is a lot of questions about convert a Response in dict but didn’t found any about converting a dict to a Response.

So how to make my patch callable by the method json() ?

>Solution :

Firstly we need to figure what is required by requests.models.Response‘s method .json in order to work, this can be done by scrying source code available at github – requests.models source. After reading requests.models.Response.json body we might conclude that if encoding is set, it does simply loads .text. text method has @property decorator, meaning it is computed when accessing .text, this in turn depend on .content which also is computed. After scrying .content it should be clear that if we set ._content value then it will be returned by .content, therefore to make fake Response which do support .json we need to create one and set .encoding and ._content of it, consider following example:

from requests.models import Response
resp = Response()
resp.encoding = 'ascii'
resp._content = b'{"x":100}'
print(resp.json())

output

{'x': 100}

Note that _content value needs to be bytes so if you have dict d then to get value to be put there do json.dumps(d).encode('ascii')

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading