How to post a request with form-data using Robotframework

curl -X ‘POST’
'https://localhost:8443/ABCD/9/XYZ?operation=CREATE&reason=10’
-H ‘accept: application/json’
-H ‘Content-Type: multipart/form-data’
-F ‘file=@bulk_insert_sample.txt;type=text/plain’

I tried this →

Create Session    bulk_download    ${BASE_URL}    verify=False
${headers}=    Create Dictionary    Authorization=Bearer ${ACCESS_TOKEN}    accept=application/json
${file_content}=    Get File    ${FILE_PATH}
&{multipart_file}=    Create Dictionary    file=( ${FILE_NAME}, ${file_content}, ${CONTENT_TYPE})
${response}=    POST On Session    bulk_download    ${ENDPOINT_CREATE}    headers=${headers}    files=${multipart_file}
Should Be Equal As Numbers    ${response.status_code}    200

But unfortunately getting , file.getContentType()= null from BE, though the file content and path is valid

Hi Nikhilesh,

A couple of things I notice right away:

  • The line starting ${headers}= Create Dictionary is missing the Content-Type: header
  • The line starting &{multipart_file}= Create Dictionary, ${CONTENT_TYPE} should be the file’s content type (e.g. text/plain) not the multipart/form-data content type

where 'content-type' is a string defining the content type of the given file

Hopefully that’s all you need :crossed_fingers:

Dave.

curl -X ‘POST’
'https://localhost:8443/ABCD/9/XYZ?operation=CREATE&reason=10’
-H ‘accept: application/json’
-H ‘Content-Type: multipart/form-data’
-F ‘file=@bulk_insert_sample.txt;type=text/plain’

this culr command was working

But

*** Settings ***
Library RequestsLibrary
Library BuiltIn
Library String
Library OperatingSystem

*** Variables ***
${BASE_URL} https://localhost:8003/
${ACCESS_TOKEN} eyJhbGciOiNiJ9.eyJzdWIiOiEwMH0.pMIZh-HxHFrdHmKMjg
${ENDPOINT_CREATE} /eq/9/optxyz?opt=CREATE&rn=10
${FILE_PATH} C:/*******/bulkinsert.txt

*** Test Cases ***
Test Upload Success
[Documentation] Test case that simulates different download scenarios
Create Session Session_download ${BASE_URL} verify=False
${headers}= Create Dictionary Authorization=Bearer ${ACCESS_TOKEN} accept=application/json Content-Type=Multipart/form-data
${file_content}= Get File ${FILE_PATH}
&{multipart_file}= Create Dictionary file=( test.txt, ${FILE_CONTENT}, text/plain)
${response}= POST On Session Session_download ${ENDPOINT_CREATE} headers=${headers} files=${multipart_file}
Should Be Equal As Numbers ${response.status_code} 200

is returning

2024-09-01 03:49:56.799 9010c85a-0160-409a-95dc-9b3b22fc0a47 ERROR - org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request

“INTERNAL_SERVER_ERROR”,“description”:“Failed to parse multipart servlet request”

Hi Nikhilesh,

I think you need to change this line:

${file_content}=    Get File    ${FILE_PATH}

with this:

${file_content}=    Get File For Streaming Upload    ${FILE_PATH}

Also FYI watch your variable names ${file_content} is not the same as ${FILE_CONTENT}

Dave.

I change as per your suggestion but the error is same

2024-09-01 04:20:36.723 15a2bd3e-0f15-42d9-8a74-98023c25c550 ERROR - org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request

Hi Nikhilesh,

I wasn’t sure where to guide you from here, but after thinking on it a bit, I would try running the curl command with a -v switch and saving the request headers and request body from that command and compare it to what you have from requests library

Look at the content-length header and make sure they are the same size when uploading the same file

Then check the other headers and see if any are missing or extra.

Dave.

Hi Nikhilesh,

I also noticed these line breaks:

They looked a little odd to me, which made me look close and notice the & on &{multipart_files} on the POST On Session line, I think on that line it should be a $ not &, so you could try that too.

Dave.

I tried with a different way →

File Valid
${headers}= Create Dictionary Authorization=Bearer ${ACCESS_TOKEN} accept=application/json Content-Type=multipart/form-data
Create Session bulk_upload ${BASE_URL} verify=False
${response}= POST On Session bulk_upload ${ENDPOINT_BULK_UPLOAD} headers=${headers} files={“file”: (“bulkinsert.txt”, open(“${FILE_PATH}”, “rb”), “${CONTENT_TYPE}”)}
Should Be Equal As Numbers ${response.status_code} 200

Now getting this error__>

${response} = RequestsLibrary . POST On Session bulk_upload ${ENDPOINT_BULK_UPLOAD} headers=${headers} files={“file”: (“bulkinsert.txt”, open(“${FILE_PATH}”, “rb”), “${CONTENT_TYPE}”)}

Documentation: Sends a POST request on a previously created HTTP Session.
Start / End / Elapsed: 20240912 09:21:52.465 / 20240912 09:21:52.474 / 00:00:00.009

09:21:52.468 FAIL ValueError: cannot encode objects that are not 2-tuples

Hi Nikhilesh,

At least that error is telling you what’s wrong:
This tuple is a 3-tuple not a 2-tuple

(“bulkinsert.txt”, open(“${FILE_PATH}”, “rb”), “${CONTENT_TYPE}”)

try changing it to:

(“bulkinsert.txt”, open(“${FILE_PATH}”, “rb”))

I know the documentation said it supports 3-tuple and 4-tuples, but perhaps you found a bug in bulk_upload or the documentation?

Dave.

I am able to fix the issue. I use this

File Valid
${headers}= Create Dictionary Authorization=Bearer ${ACCESS_TOKEN} accept=application/json
Create Session bulk_upload ${BASE_URL} verify=False
${file_content}= Get File ${FILE_PATH}
${file_tuple}= Create List bulkinsert.txt ${file_content} ${CONTENT_TYPE}
${file}= Create Dictionary file=${file_tuple}
${response}= POST On Session bulk_upload ${ENDPOINT_BULK_UPLOAD} headers=${headers} files=${file}
Should Be Equal As Numbers ${response.status_code} 200

Thank you for your kind support :slight_smile:

1 Like