Requests library new keyword Post On Session issue

I have a test suite for an rest api that I implemented over the Requests Library, and it was working fine.
Last week, a new version of this library was released and I got some warnings regarding to deprecated keywords such post request, get request and others.

So I started to migrate the old implementation to the new one.

But with the new version, I an unable to pass a json to a simple post request.
I used to pass the json as a dictionary, but for some reason the body of the request is always None.

Currently, my keyword has the following implementation:

I Send a Post Request
    [Arguments]    ${alias}    ${uri}     ${data}=None    ${json}=None     ${msg}=None    ${headers}=${EMPTY}    ${timeout}=${EMPTY}
    ${kwargs}    Create Dictionary
    ${hasValue}    Run Keyword and return status     Should not be empty    ${headers}
    Run Keyword if    ${hasValue}    Set To Dictionary    ${kwargs}    headers=${headers}
    ${hasValue}    Run Keyword and return status     Should not be empty    ${timeout}
    Run Keyword if    ${hasValue}    Set To Dictionary    ${kwargs}    timeout=${timeout}
    ${response}=    Post On Session     ${alias}    ${uri}    data=${data}    json=${json}     expected_status=any    msg=${msg}     &{kwargs}
    Set Test Variable    ${response}

When executed in a test, it sends and get as response:

 POST Request : url=http://localhost:8080/logon 
 path_url=/logon 
 headers={'User-Agent': 'python-requests/2.25.1', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Authorization': 'Bearer ******', 'X-Session-ID': '', 'X-Flow-ID': 'd933b413-1681-4eaf-9fee-ae4c3d82b9d8', 'X-Device-Info-UUID': '217ff7f7-1cb8-4760-8f52-35cdead8b1e0', 'X-Customer-ID': '123456', 'Content-Length': '4'} 

body=None

POST Response : url=http://localhost:8080/logon 
 status=415, reason= 
 headers={'Accept': 'application/json', 'X-Content-Type-Options': 'nosniff', 'X-XSS-Protection': '1; mode=block', 'Cache-Control': 'no-cache, no-store, max-age=0, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'X-Frame-Options': 'DENY', 'Content-Type': 'application/json', 'Transfer-Encoding': 'chunked', 'Date': 'Mon, 01 Feb 2021 15:16:20 GMT', 'Keep-Alive': 'timeout=60', 'Connection': 'keep-alive'} 

body={“timestamp”:“2021-02-01T12:16:20.568563-03:00”,“message”:“Content type ‘’ not supported”,“error”:“Unsupported Media Type”,“status”:415,“path”:"/logon"}

Just a wild guess because the error says points out that content-type is empty:

try:

${content-type}=  Create Dictionary  content-type  application/json`

and then add headers=${content-type}. as parameter to Post On Session session …

Also, posting data and json in one go sounds bit fishy …

It is still sending None in the body of the request

I could solve the problem. Although the new keywords documentation says that json and data are parameter, it worked for me only when I passed them as **kwargs, as a dictionary.
I created a new keyword to build this dictionary

Create Arguments Dictionary
[Arguments] ${data}=${EMPTY} ${json}=${EMPTY} ${params}=${EMPTY} ${headers}=${EMPTY} ${files}=${EMPTY} ${allow_redirects}=${EMPTY} ${timeout}=${EMPTY}
${kwargs} Create Dictionary
${hasValue} Run Keyword and return status Should not be empty ${headers}
Run Keyword if ${hasValue} Set To Dictionary ${kwargs} headers=${headers}
${hasValue} Run Keyword and return status Should not be empty ${timeout}
Run Keyword if ${hasValue} Set To Dictionary ${kwargs} timeout=${timeout}
${hasValue} Run Keyword and return status Should not be empty ${data}
Run Keyword if ${hasValue} Set To Dictionary ${kwargs} data=${data}
${hasValue} Run Keyword and return status Should not be empty ${params}
Run Keyword if ${hasValue} Set To Dictionary ${kwargs} params=${params}
${hasValue} Run Keyword and return status Should not be empty ${files}
Run Keyword if ${hasValue} Set To Dictionary ${kwargs} files=${files}
${hasValue} Run Keyword and return status Should not be empty ${allow_redirects}
Run Keyword if ${hasValue} Set To Dictionary ${kwargs} allow_redirects=${allow_redirects}
${hasValue} Run Keyword and return status Should not be empty ${json}
Run Keyword if ${hasValue} Set To Dictionary ${kwargs} json=${json}
[Return] ${kwargs}

Then I refactored the post keyword:

I Send a Post Request
[Arguments] ${alias} ${uri} ${data}=${EMPTY} ${json}=${EMPTY} ${params}=${EMPTY} ${headers}=${EMPTY} ${files}=${EMPTY} ${allow_redirects}=${EMPTY} ${timeout}=${EMPTY}
${kwargs} Create Arguments Dictionary data=${data} json=${json} params=${params} headers=${headers} files=${files} allow_redirects=${allow_redirects} timeout=${timeout}
${response}= Post On Session ${alias} ${uri} expected_status=any &{kwargs}
Set Test Variable ${response}

It worked fine, not only for post, but for get, patch and put. Other methods we don’t have in our api.

Hi, as said on slack I opened an issue to investigate the case of both data and json passed.

It’s quite strange the solution you found should not be necessary I’ll have a look.

1 Like

If no timeout is specified explicitly, requests do not time out.

I want you to thank for your time of this wonderful read!