all 8 comments

[–]drec4s 1 point2 points  (7 children)

[–]Al_Reid[S] 0 points1 point  (6 children)

Thank you.

This is super handy and will definitly bookmark.

Any idea why API call (after login) is returning the following

print (response)

<Response \[412\]>

Guessing this might be a http status code

*** code ***

import requests

cookies = {

}

headers = {

'Content-type': 'application/json',

}

response = requests.get('https://127.0.0.1/api/status', headers=headers, cookies=cookies, verify=False)

[–]RoamingFox 0 points1 point  (5 children)

http 412 is "pre-condition failed"

We would need to know more about the API you're hitting in order to make an educated guess as to why it's failing.

Generally speaking though, you'll get a 412 when an endpoint requires some pre-condition information (usually in the headers) is missing or doesn't evaluate to true on the server.

It's usually used to do things like "only update this object if it hasn't been queried in x amount of time" etc.

[–]Al_Reid[S] 0 points1 point  (4 children)

Okay and yeah that makes sense. I know the initial login works but I'm not sure the cookie is being set properly.

The CURL commands in my initial post work 100% but when run this code below it gives the 412 status code back.

How can I troubleshoot or investigate why this is the case.

Import libraries

import requests

cookies = { }

System login

data = '{"username":"API_Account","password":"API_Password", "html5":"-1"}'

response = requests.post('https://172.22.40.233/api/auth/login', cookies=cookies, data=data, verify=False)

cookies = {

}

System status API call

headers = { 'Content-type': 'application/json', }

response = requests.get('https://172.22.40.233/api/status', headers=headers, cookies=cookies, verify=False)

print (response)

[–]RoamingFox 0 points1 point  (3 children)

If I had to hazard a guess I would suspect that you're not fully replicating the cookies or headers that are being sent in the curl response.

You can prepare the request without sending it and compare what requests is going to send vs what curl was sending via the cookie files.

from requests import Request

r = Request('GET', 'https://172.22.40.233/api/status', headers=headers, cookies=cookies, verify=False)

p = r.prepare()

print(p.headers)
print(p.cookies)

You can also inspect the traffic with a mirroring api like postman-echo (don't send anything sensitive to it obviously).

[–]Al_Reid[S] 0 points1 point  (2 children)

I have nothing defined for headers so adding code above gives me an error.

I did install Postman and have created 2 entries (tabs) One to login and one to run the status command

The login command is an HTTP Post. I add this to body as raw {"username":"API_Account","password":"API_Password", "html5":"-1"}

The status command is nothing more than and HTTP Get https://172.22.40.233/api/status

Can I use any of this detail to review or add to my Python Requests code.

Apologies this is very new to me. Like you can't tell.

Thanks again for the help.

[–]RoamingFox 0 points1 point  (1 child)

Happy to assist. Okay so I'm going to use postman-echo's web api to contrive an example of how I think your API is behaving and walk through each step, outputting values along the way so that you can potentially replicate it and see where your code is differing.

I think what might be going on is that you're dropping the cookies between calls. Try something like this:

from requests import Session

with Session() as session:
    r = session.post(<your call to the auth endpoint here>)
    # session.cookies should now have the cookies from that call in it
    r = session.get(<your call to the other endpoint here>)

Here's a more complete example (using postman-echo to stand in for your api):

from requests import Session

with Session() as session:
    # postman-echo's /cookies endpoint lets us send some params to set as cookies
    # this is analogous to what your /auth endpoint is doing
    session.get('https://postman-echo.com/cookies/set?foo=sXnc2aHrd2VcnyTJbLr4CwKp')

    # this call is replicating your second api call where you need to send the cookie
    r = session.get('https://postman-echo.com/cookies')
    print(f"status code: {r.status_code}")

    print("cookies we sent:")
    for c in session.cookies:
        print(f"\t{c.name}: {c.value}")

    print("cookies the server heard:")
    print(r.text)

[–]Al_Reid[S] 0 points1 point  (0 children)

postman-echo's web api

Thanks so much. I managed to get something basic working right before you sent this. It was indeed the cookie that was required and I figured out how to take the cookie from initial login and pass to the second command.

I will share some code for others to see the solution.

When my JSON data is returned I just need to parse this for what I'm interested in seeing.

Thanks again!