Search code examples
pythonpostpython-requestspostman

How do I use the python requests package to POST a .csv file, from within a .zip folder, using form-data and a parameters file?


I am currently attempting to replicate a manual API call I have made in POSTMAN via Python.

I am POSTing a .csv file from within a .zip folder. To do so, I have to use form-data within the body of the request, add the inputFile with the value being the file itself and the Content-Type: application/zip. I also have a file for the parameters, which is JSON (see attached).

POSTMAN Body

I have tried a couple of different methods to POST the data, but I am primarily receiving 415 (unsupported media) response. Now, when I was doing this via POSTMAN, I did get this error a couple of times when the parameters file or the zip file Content-Type wasn't properly specified.

import requests
import boto3

import_headers = {'Content-Type': 'multipart/form-data; boundary=<calculated when request is sent>',
                  'Accept-Encoding': 'gzip, deflate, br',
                  'Connection': 'keep-alive',
                  'Accept': '*/*',
                  'Authorization': 'Bearer '+access_token}
test_file = open(r'C:\{filePath}\test_undelimited_MKII.zip', 'rb')
params_file = open(r'C:\{filePath}\paremeters.json', 'rb')
params_obj = {
  "mode" : "CREATE_UPDATE",
  "encoding" : "UTF-8",
  "format" : {
    "separator" : ";",
    "endOfLine" : "\r\n",
    "enclosing" : "\"",
    "escaping" : "\""
  },
  "reportRecipients": [
    {emailAddress}
  ]
}

requests.post(url, headers=import_headers, params={"archive": ("paremeters.json", params_file)}, files={"archive": ("test_undelimited_MKII.zip", test_file)})

requests.post(url, headers=import_headers, params=params_obj, files={"archive": ("test_undelimited_MKII.zip", test_file)})

N.B. I am relatively new to Python, so be gentle, please.


Solution

  • When making a multipart/form-data request with a file upload using the requests library in Python, you need to construct the request properly to ensure that the file and parameters are sent correctly. Here's some example of how you can modify your code to make the API call:

    enter code here
    
    import requests
    
    url = "<API_URL>"
    access_token = "<ACCESS_TOKEN>"
    
    headers = {
        "Authorization": "Bearer " + access_token
    }
    
    files = [
        ("archive", ("test_undelimited_MKII.zip", open(r"C:\{filePath}\test_undelimited_MKII.zip", "rb"), "application/zip")),
        ("params", ("parameters.json", open(r"C:\{filePath}\parameters.json", "rb"), "application/json"))
    ]
    
    response = requests.post(url, headers=headers, files=files)
    
    print(response.status_code)
    print(response.text)