0

I have an API which requires a multipart/form-data content to be send in the body in order to upload a file(image) using POST. I have chosen to use python's requests module as it's easy for newbies like me.There are two form parameters to pass; one is called file, which should be the actual file data and the other is called file-data, which is a dictionary object as below:

    {"param1": param_val,"param2":param_val1}

I have seen http://docs.python-requests.org/en/master/user/quickstart/#post-a-multipart-encoded-file but it doesn't speak about passing form parameters, i.e as if these parameters were values being passed from within a web form which provides placeholders for the file name and the other parameters. Note that if I pass ordinary parameters to the API call like:

    r = requests.post(url, headers= headers,params=params)

I would end up sending the parameters after the URL as in URL?param1=param_val>...etc which doesn't work in this case. So I basically need a way to send the form parameters mentioned above as form data of the request. If I could get some guidance around the syntax of the POST call to make in the scenario it would help a lot-

****edited for more clarity****

The desired HTTP trace of my POST request is as shown below:

    POST <application URL>
    Host: <Host server name>
    Authorization: Basic ABCDXXXX
    Cache-Control: no-cache
    Postman-Token: XXXXXX-ABACC-XXXXX
    Content-Type: multipart/form-data; boundary=----     

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

    {"description": "Sample desc","languageCode": "en" }
    ------WebKitFormBoundaryABCXXXXXXXXXXXXX
    Content-Disposition: form-data; name="file"; filename=""
    Content-Type: 


    ------WebKitFormBoundaryWWWWXXXXXXXXXXXX--

If I use the form:

    r = requests.post(url,headers=headers,data=filedata,files=files)

I end up getting an error message '400 199-repeated entities[]' which on closer investigation reveals that the request is trying to unpack the tuples in my file-data variable and ends up creating two content boundaries, one for the description and other for the languagecode. Is there a way I can just make it pass file-data in the form parameters just once as shown above?

****end of edit*****

Thanks in advance- Regards

  • See the duplicate; you specify parameters in `data` and files with the `files` parameter. – Martijn Pieters Jan 23 '17 at 18:12
  • Thanks @Martijn. I saw the thread you referred but I want to understand the why the API documentation asks me to use Type: multipart/form-data. Is it to specifically enforce that I am passing form data in my content? Do I have to mention the type as a header parameter or is it implicit? – Abhishek Ghosh Jan 24 '17 at 04:22
  • `multipart/form-data` is the only encoding that can upload files and key-value data in the same request body. See [application/x-www-form-urlencoded or multipart/form-data?](//stackoverflow.com/q/4007969) – Martijn Pieters Jan 24 '17 at 07:21
  • @Martijn my problem is still unsolved. I have followed your suggestions but I keep getting the same error. The problem is to unpack the tuples in a way that the API expects and I'm unable to do so. I have raised another related question [here](http://stackoverflow.com/questions/42341737/python-assign-literal-value-of-a-dictionary-to-key-of-another-dictionary). Would you be able to look into and check if you can help? Thanks in advance- – Abhishek Ghosh Feb 21 '17 at 09:31
  • You already got help there. You can't just post a dictionary in a form field value. – Martijn Pieters Feb 21 '17 at 09:33
  • But my form parameter is of type _string_. I cannot do json.dumps(filedata) as it would then cause it to get unpacked during runtime. The 2nd part of my nested dictionary is expected as a complete value, i.e. `file-data:{"key1":"value1","key2","value2"....}` I tried using `"file-data":"{"key1":"value1","key2","value2"....}"` but requests still doesn't parse it correctly – Abhishek Ghosh Feb 21 '17 at 09:43
  • Put that on you other question. Make sure you clearly explain what kind of POST you expect to send. If that is meant to be a string, then create a proper string. Escape the quotes or use single quotes around the value. – Martijn Pieters Feb 21 '17 at 09:45

0 Answers0