DEV Community

loading...

Make ✨ 🍰 ✨ requests act like jQuery when passing nested objects to data/payload

TAHRI Ahmed R.
・2 min read

Once upon a time

I, once was stuck when using python-requests in order to poke a PHP backend.

You may currently face this issue as Requests does not support dict with depth greater than 1 on parameter data for a x-www-form-urlencoded based request.

PHP/jQuery $.params support this syntax out of the box. As requests is not about supporting the way PHP/jQuery $.params work internally, this PR maybe doomed.

To reproduce

from requests import post
from pprint import pprint

if __name__ == '__main__':

    response = post(
        'https://api.ipify.org?format=json',
        {
            'auth_user': 'test',
            'auth_pwd': 'test',
            'json_data': {
                'operation': 'core/get',
                'class': 'ServiceChange',
                'key': 'SELECT ServiceChange WHERE id=429',
                'output_fields': 'request_state',
                'h': {
                    't': 1
                }
            }
        }
    )

    pprint(
        response.request.body
    )

Enter fullscreen mode Exit fullscreen mode

What happen now

print(response.request.body)
# auth_user=test&auth_pwd=test&json_data=operation&json_data=class&json_data=key&json_data=output_fields&json_data=h
Enter fullscreen mode Exit fullscreen mode

Something should happen when passing nested dict. This behavior is wrong. We loss data between passing and sending. At least raise a warning or whatnot.

✨ What should have happened

print(response.request.body)
# auth_user=test&auth_pwd=test&json_data%5Boperation%5D=core%2Fget&json_data%5Bclass%5D=ServiceChange&json_data%5Bkey%5D=SELECT+ServiceChange+WHERE+id%3D429&json_data%5Boutput_fields%5D=request_state&json_data%5Bh%5D%5Bt%5D=1
Enter fullscreen mode Exit fullscreen mode

Why ?

  • [x] requests is on a higher level than urllib, this does not make sense in urllib, but can in requests
  • [x] PHP and Ruby on Rails support this syntax out of the box, and is used by more than 30 % of the remote backends.
  • [x] This PR would make it more beginner friendly, advanced users that are looking for test=foo&test=baz are more likely to encode their payload manually. Not the other way around.
  • [x] This change does not break or change actual behavior expect for the multivalued param case which is a very rare case in my opinion.

How to use this patch ?

Simply use my fork for the time being, you could support my PR too.

Patch : tree/patch-1
PR : https://github.com/psf/requests/pull/5253

Discussion (1)

Collapse
toolsformarketers profile image
toolsformarketers

thanks for your contribution, you saved me time struggling where the issue is :)
Just adding those line for anyone else who's facing the same problem.

pip install https://github.com/Ousret/requests/archive/patch-1.zip 
Enter fullscreen mode Exit fullscreen mode

or update requests by the url in your requirements.txt.