Paul Nobrega
Paul Nobrega

Reputation: 3

Django DRF Post with files and data works in Postman, not Python. No TemporaryUploadedFile

Running a Django App locally, i can use Postman to upload a zip file along with some dict data. Breaking the application in 'def Post()' i can see that Postman's successful upload:

request.data = <QueryDict: {'request_id': ['44'], 'status': [' Ready For Review'], 'is_analyzed': ['True'], 'project': ['test value'], 'plate': ['Plate_R0'], 'antigen': ['tuna'], 'experiment_type': ['test'], 'raw_file': [<TemporaryUploadedFile: testfile.zip (application/zip)>]}>

Postman offers the following python code to replicate these results in my python script:

import requests

url = "http://127.0.0.1:8000/api/upload/"

payload = {'request_id': '44',
'status': '  Ready For Review',
'is_analyzed': 'True',
'project': 'test value',
'plate': 'Plate_R0',
'antigen': 'tuna',
'experiment_type': 'test'}
files = [
  ('raw_file', open(r'C:/testfile.zip','rb'))
]
headers = {
  'Content-Type': 'application/x-www-form-urlencoded'
}

response = requests.request("POST", url, headers=headers, data = payload, files = files)

print(response.text.encode('utf8'))

running this code directly and retrieving the request.data (server side) i see the binary representation of the xlsx file is in the object and the payload data is not there (this is the error in the response).

How do i get my python script to produce the same server-side object as postman? Specifically how do i upload my data such that the file is represented as: <TemporaryUploadedFile: testfile.zip (application/zip)>

Thanks.

Upvotes: 0

Views: 778

Answers (1)

Paul Nobrega
Paul Nobrega

Reputation: 3

Turns out, inspection of the object posted by Postman shows that it was using multipart-form upload. Searching around i found this answer to a related question to describe posting as multi-part: https://stackoverflow.com/a/50595768/2917170 .

The working python is as follows:

    from requests_toolbelt import MultipartEncoder
    url = "http://127.0.0.1:8000/api/upload/"
    zip_file = r'C:/testfile.zip'

    m = MultipartEncoder([('raw_file', (os.path.basename(zip_file), open(zip_file, 'rb'))),
                          ('request_id', '44'),
                          ('status', 'Ready For Review'),
                          ('is_analyzed', 'True'),
                          ('project', 'test value'),
                          ('plate', 'Plate_R0'),
                          ('antigen', 'tuna'),
                          ('experiment_type', 'test')])

    header = {'content-type': m.content_type}
    response = requests.post(url, headers=header, data=m, verify=True)

Upvotes: 0

Related Questions