XML file upload in requests library

I am attempting to send a POST request which passes an XML file to an endpoint. I don’t understand how it should be written in the Robot Framework Requests Library.

The code below is written in Python and works great. For some reason I’m having trouble converting it to the Robot Framework Request Library equivalent. I’m thinking I just don’t understand the documentation properly.

Python Code that works:

    myfiles = {'importFile': ('settings.xml',open('c:/temp/settings.xml', 'rb'), 'application/xml')}
    url = 'http://localhost/importSettingsAsXML.js'
    r = requests.post(url, files=myfiles)

Hi @asdf,

Let’s break it down into bite size pieces and tackle it piece at a time, this might be a bit long winded, but the process I show you here can be used with any problem.

  • Lets start with this line:
myfiles = {'importFile': ('settings.xml',open('c:/temp/settings.xml', 'rb'), 'application/xml')}
  • actually this line has 3 parts to it.

    • It’s creating a JSON body for the post body,
    • but inside the construction of the JSON body is a tuple with the file information
      • actually a tuple is not valid in JSON, perhaps it gets converted to a list? On further checking the json module in python does indeed convert the tuple into a list so we’ll use a list as that’s easier in robot framework.
    • and inside the construction of the tuple it’s doing a file read so the content of the file is being embedded inside a the second value of the tuple, so as this is the inner most part we’ll start here
  • So starting with the file read: open('c:/temp/settings.xml', 'rb')

    • this is a binary file read, the equivalent of that in robot framework is Get Binary File from OperatingSystem Library
    • So we’ll need to add the OperatingSystem Library
    • and call Get Binary File
    • so far we have:
*** Settings ***
Library    OperatingSystem

*** Test Cases ***
Upload XML File
    ${filedata}=    Get Binary File    c:/temp/settings.xml
  • Now we can move on to this part: ('settings.xml',open('c:/temp/settings.xml', 'rb'), 'application/xml')
    • as I mentioned before we’ll use a list instead of a tuple as it will be converted to a list anyway, for this we use Create List from the Builtin Library
    • so now we have
*** Settings ***
Library    OperatingSystem

*** Test Cases ***
Upload settings.xml
    ${filedata}=    Get Binary File    c:/temp/settings.xml
    @{imprtfile}=    Create List    settings.xml     ${filedata}    application/xml
  • Now we can complete the construction of the first line (the post body): myfiles = {'importFile': ('settings.xml',open('c:/temp/settings.xml', 'rb'), 'application/xml')}
    • this is a dictionary with a single key value pair, we’ve already constructed the value, so now we just use Create Dictionary from the Builtin Library
    • so now we have
*** Settings ***
Library    OperatingSystem

*** Test Cases ***
Upload settings.xml
    ${filedata}=    Get Binary File    c:/temp/settings.xml
    @{imprtfile}=    Create List    settings.xml     ${filedata}    application/xml
    &{myfiles}=    Create Dictionary    importFile=${imprtfile}
  • Now we can move on to the next line: url = 'http://localhost/importSettingsAsXML.js'
    • this is a string variable so we can use Set Variable from Builtin
    • so now we have
*** Settings ***
Library    OperatingSystem

*** Test Cases ***
Upload settings.xml
    ${filedata}=    Get Binary File    c:/temp/settings.xml
    @{imprtfile}=    Create List    settings.xml     ${filedata}    application/xml
    &{myfiles}=    Create Dictionary    importFile=${imprtfile}
    ${url}=    Set Variable    http://localhost/importSettingsAsXML.js
  • And now we come to the final line r = requests.post(url, files=myfiles)
    • this is the POST keyword from RequestsLibrary
    • So we’ll need to tell robot framework that we want to use keywords from RequestsLibrary
    • and call the POST keyword
    • so now we have
*** Settings ***
Library    OperatingSystem
Library    RequestsLibrary

*** Test Cases ***
Upload settings.xml
    ${filedata}=    Get Binary File    c:/temp/settings.xml
    @{imprtfile}=    Create List    settings.xml     ${filedata}    application/xml
    &{myfiles}=    Create Dictionary    importFile=${imprtfile}
    ${url}=    Set Variable    http://localhost/importSettingsAsXML.js
    ${resp}=    POST    ${url}  json=${myfiles}

Hopefully you don’t just copy the answer at the end, but follow the process of how I got there, hopefully you’ll also learn to process of problem solving :crossed_fingers:

Dave.

1 Like

I want to thank you for your detailed response, I’m sure this took a while to write out and I really appreciate it. As I’m sure you’re aware, your last sentence is quite patronizing and perhaps a little ignorant. It is probably a good idea to not make assumptions about people whom you do not know.

In case you were curious, I was stuck because I didn’t know that tuples were converted to lists in Robot Framework. Which is why I was able to write the code in Python but not in Robot Framework. The documentation on the Robot Framework RequestsLibrary only describes providing tuples for the files attribute which led to my confusion.

The final line should read files=${myfiles} instead of json=${myfiles}. So I wasn’t apple to just copy paste :slight_smile:

Once again, I want to thank you sincerely because I was stuck on this for a couple days not getting anywhere. In the future, you can probably avoid writing that last line. It was a bit of a bummer dude.

Thanks again,

1 Like