RequestLibrary : HTTPError: For post api -400 Client Error: Bad Request for url

Hi all

I am using robot framework request library to automate post api.
I have json payload and and some of value from that are need to pass dynamically.

I am able to successfully post request if I put static content in json file.

but as I want to pass dynamic content, I want to use dictionary. My code is as below

${header}=    Create Dictionary    Content-Type=application/json;charset=utf-8    Accept=application/json;charset=utf-8
#    ${proxyDict}=    Create Dictionary    http=URL_proxy_http    https=URL_proxy_https
    Create Session    myssion    ${api_url}    headers=${header}    disable_warnings=1
    ${file_data}=   Get Binary File    ../../${/}Resources${/}data.json
    ${body}=    Create Dictionary   customerName=rass   status=false  rejectionReason=${KWagrs}   filingPeriod=04-2022   regionCode=33
    Log    ${body}
    ${response}=    Post On Session    myssion    /api/v1/create    json=${body}

On execution I am getting below error- Anyone please help

Below is working code with static content from json file -
${header}= Create Dictionary Content-Type=application/json;charset=utf-8 Accept=application/json;charset=utf-8
Create Session myssion ${api_url} headers=${header} disable_warnings=1
${file_data}= Get Binary File …/…/${/}Resources${/}data.json
${body}= Create Dictionary customerName=rass status=false rejectionReason=${KWagrs} filingPeriod=04-2022 regionCode=33
Log ${body}
${response}= Post On Session myssion /api/v1/create data=${file_data}

Note : I tried changing json= instead of data= and &{body}= instead ${body}

Suggest me any other way to pass dynamic content and correct json file?

Hi Bk-ava,

From looking at the error message returned by your app server, it looks like the solution might be as simple as changing this line:

to:

&{body}=    Create Dictionary   customerName=rass   status=False  rejectionReason=${KWagrs}   filingPeriod=04-2022   regionCode=33

Notice the & replacing $ in body variable and the capital F in status=False, the server is complaining you sent a text string ‘false’ when it was expecting a boolean which is why i’m making this suggestion.

If that doesn’t work, then can you add a line Log ${file_data} and show us the result of both Log for ${file_data} and ${body} and hopefully we can spot the difference.

Another thing you can do is put exactly the same values in the ${body} dictionary as are in the static file then do something like this:

Should Be Equal		${body}		${file_data}

or even try Dictionaries Should Be Equal

Dictionaries Should Be Equal		${body}		${file_data}

Hope that helps,

Dave.

@damies13

I tried suggested ways–

  1. modified status=false to status=False ----not working

  2. Changed to & body -------not working

  3. Printed both ${body} ${file_data}

    ${header}= Create Dictionary Content-Type=application/json;charset=utf-8 Accept=application/json;charset=utf-8

    ${proxyDict}= Create Dictionary http=URL_proxy_http https=URL_proxy_https

     Create Session    myssion    ${api_url}    headers=${header}    disable_warnings=1
     ${file_data}=   Get Binary File    ../../${/}Resources${/}data.json
     &{body}=    Create Dictionary   id=100   customerName=rass   status=False  rejectionReason=failed   filingPeriod=04-2022   regionCode=33
     ${body1}=    Create Dictionary   id=100   customerName=rass   status=False  rejectionReason=failed   filingPeriod=04-2022   regionCode=33
     Log    ${body1}
     Dictionaries Should Be Equal    ${body1}    ${file_data}
    

    Should Be Equal &{body} ${file_data}

     ${response}=    Post On Session    myssion    /api/v1/create    data=${body}
     Dictionaries Should Be Equal    ${body1}    ${file_data}
    

Hi Bk-ava,

I think your close, don’t worry with the should be equal or Dictionaries Should Be Equal as the file is read as a binary string so is not going to be equal unless we either json decode the string or json encode the dictionary.

try it like this:

Create Session    myssion    ${api_url}    headers=${header}    disable_warnings=1
&{body}=    Create Dictionary   customerName=rass   status=False  rejectionReason=${KWagrs}   filingPeriod=04-2022   regionCode=33
${response}=    Post On Session    myssion    /api/v1/create    json=${body}

The post on session needs to be json not data when sending a dictionary, it’s done as the document said it would when you passed a dictionary o data and urlencoded the values not json encoded them

If that still doesn’t work It also might be useful to do this:

Create Session    myssion    ${api_url}    headers=${header}    disable_warnings=1
${file_data}=   Get Binary File    ../../${/}Resources${/}data.json
${response}= Post On Session myssion /api/v1/create data=${file_data}


&{body}=    Create Dictionary   customerName=rass   status=False  rejectionReason=${KWagrs}   filingPeriod=04-2022   regionCode=33
${response}=    Post On Session    myssion    /api/v1/create    json=${body}

Then we can compare the difference between request bodies and headers on both Post On Session’s so we can see what’s different.

There are other options e.g.:

  • construct the body as a string and then send that string as the post data (basically similar to what you are doing with the file)
  • convert the dictionary to a json string, I think there was a library that did that, otherwise calling native python to do it
  • then there is always RESTinstance

But I don’t think you’ll get there any quicker than trying to get your example above working, but if we don’t make any progress we can fall back to these.

Dave.

@damies13
Root cause was passing status=False treating that as string .
Converted status to bool and passed then worked
${status}= Convert To Boolean ${status}

Thank you

1 Like