Search code examples
pythonpython-requestsqualtrics

Importing Qualtrics Responses using Python Requests library


I am trying to import a csv of responses into Qualtrics using the API shown here: https://api.qualtrics.com/docs/import-responses. But, since I'm a noob at Python and (by extension) at Requests, I'm having trouble figuring out why I keep getting a 413. I've gotten this far:

formTest = {
    'surveyId': 'my_id',
    'file': {
        'value': open('dataFiles/myFile.csv', 'rb'),
        'options': {
            'contentType': 'text/csv'
        }
    }
}

headersTest = {
    "X-API-TOKEN": "my_token",
    'content-type': "multipart/form-data"
}

r = requests.request("POST", url, data=formTest, headers=headersTest)
print(r.text)

The format for the formTest variable is something I found when looking through other code bases for an angular implementation of this, which may not apply to a python version of the code. I can successfully use cUrl, but Python Requests, in my current situation is the way to go (for various reasons).

In a fit of desperation, I tried directly translating the cUrl request to python requests, but that didn't seem to help much either.

Has anyone done something like this before? I took a look at posts for importing contacts and the like, but there was no luck there either (since the data that needs to be sent is formatted differently). Is there something I am missing?


Solution

  • It's best not to mix post data and files but use two separate dictionaries. For the files you should use the files= parameter, because it encodes the POST data as a Multipart Form data and creates the required Content-Type headers.

    import requests
    
    url = 'Qualtrics API' 
    file_path = 'path/to/file'
    file_name = 'file.name'
    
    data = {'surveyId':'my_id'}
    files = {'file' : (file_name, open(file_path, 'rb'), 'text/csv')}
    headers = {'X-API-TOKEN': 'my_token'}
    
    r = requests.post(url, data=data, files=files, headers=headers)
    print(r.text)
    

    The first value in files['file'] is the file name (optional), followed by the file object, followed by the file content type (optional).
    You will find more info in the docs: Requests, POST a Multipart-Encoded File.