0

I am trying to form a web payload for a particular request body but unable to get it right. What I need is to pass my body data as below

data={'file-data':{"key1": "3","key2": "6","key3": "8"}}

My complete payload request looks like this

payload={url,headers, data={'file-data':{"key1": "3","key2": "6","key3": "8"}},files=files}

However, when I pass this, python tries to parse each individual key value and assigns to the 'file-data' key like this

    file-data=key1
    file-data=key2
    file-data=key3

and so on for as many keys I pass within the nested dictionary. The requirement however, is to pass the entire dictionary as a literal content like this(without splitting the values by each key):

    file-data={"key1": "3","key2": "6","key3": "8"}

The intended HTTP trace should thus ideally look like this:

    POST /sample_URL/ HTTP/1.1
    Host: sample_host.com
    Authorization: Basic XYZ=
    Cache-Control: no-cache
    Content-Type: multipart/form-data; boundary=----UVWXXXX

    ------WebKitFormBoundaryXYZ
    Content-Disposition: form-data; name="file-data"

    {"key1": "3","key2": "6","key3":"8" }
    ------WebKitFormBoundaryMANZXC
    Content-Disposition: form-data; name="file"; filename=""
    Content-Type: 


    ------WebKitFormBoundaryBNM--

As such, I want to use this as part of a payload for a POST request(using python requests library). Any suggestions are appreciated in advance-

Edit1: To provide more clarity, the API definition is this:

    Body
    Type: multipart/form-data
    Form Parameters

    file: required (file)

    The file to be uploaded
    file-data: (string)

    Example:

    {
      "key1": "3",
      "key2": "6",
      "key3": "8"
    } 

The python code snippet I used(after checking suggestions) is this:

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-

    import requests
    url = "https://sample_url/upload"
    filepath='mypath' 
    filename='logo.png'
    f=open(filepath+'\\'+filename)
    filedata={'file-data':"{'key1': '3','key2': '6','key3': '8'}"}  
    base64string = encodestring('%s:%s' % ('user', 'password').replace('\n', '')
    headers={'Content-type': 'multipart/form-data','Authorization':'Basic %s' % base64string} 


     r = requests.post(url=url,headers=headers,data=filedata,files={'file':f})
     print r.text

The error I get now is still the same as shown below:

     {"statusCode":400,"errorMessages":[{"severity":"ERROR","errorMessage":"An exception has occurred"]

It also says that some entries are either missing or incorrect. Note that I have tried passing the file parameter after opening it in binary mode as well but it throws the same error message

I got the HTTP trace printed out via python too and it looks like this:

    send: 'POST sample_url HTTP/1.1
    Host: abc.com
    Connection: keep-alive
    Accept-Encoding: gzip,deflate
    Accept: */*
    python-requests/2.11.1
    Content-type: multipart/form-data
    Authorization: Basic ABCDXXX=
    Content-Length: 342
    --CDXXXXYYYYY
    Content-Disposition:form-data; name="file-data"
    {\'key1\': \'3\',\'key2\': \'6\'
    ,\'key3\': \'8\'}
    --88cdLMNO999999
    Content-Disposition: form-data; name="file";
    filename="logo.png"\x89PNG\n\r\n--cbCDEXXXNNNN--

1 Answers1

0

If you want to post JSON with python requests, you should NOT use data but json:

r = requests.post('http://httpbin.org/post', json={"key": "value"})

I can only guess that you are using data because of your example

payload={url,headers, data={'file-data':{"key1": "3","key2": "6","key3": "8"}},files=files}

Whis is not valid python syntax btw.

  • I am using the data parameter as I want to pass named elements to the request body. I tried json as you suggested and the trace shows that file data is not being passed. Perhaps, a code snippet as below might help `filedata={"key1": "3","key2": "6","key3": "8"} f=open(filepath+'\\'+filename)headers={'Content-type': 'multipart/form-data','Authorization':'Basic %s' % base64string} r = requests.post(url,headers=headers,json={'file-data':filedata},files={'file':f})print r.status_code print r.content ` – Abhishek Ghosh Feb 20 '17 at 11:29
  • I just saw that you are using `data` **AND** `files`. How is that supposed to work? Have you read: http://docs.python-requests.org/en/master/user/quickstart/#post-a-multipart-encoded-file? It is still not clear what you are trying to do. – Christian Eichelmann Feb 20 '17 at 12:49
  • Yes, using multipart form data different form data types can be sent via POST. Check this question:[link](http://stackoverflow.com/questions/22567306/python-requests-file-upload) its possible to send data in the form body and also a file along with it. My problem is to try and ensure that I get the first form parameter correctly passed onto the request, which I'm currently unable to. The API I use expects the file+certain descriptive parameters which define the use of the file – Abhishek Ghosh Feb 20 '17 at 15:19