0

I have the following session-dependent code which must be run continuously.

Code

import requests
http = requests.Session()

while True:
    # if http is not good, then run http = requests.Session() again
    response = http.get(....)
    # process respons
    # wait for 5 seconds

Note: I moved the line http = requests.Session() out of the loop.

Issue

How to check if the session is working?

An example for a not working session may be after the web server is restarted. Or loadbalancer redirects to a different web server.

hc_dev
  • 8,389
  • 1
  • 26
  • 38
ca9163d9
  • 27,283
  • 64
  • 210
  • 413
  • You are confusing a client session with a server session. While a server session can expire, you can create a new one in the same client session. – Klaus D. May 19 '22 at 22:07

2 Answers2

5

The requests.Session object is just a persistence and connection-pooling object to allow shared state between different HTTP request on the client-side.

If the server unexpectedly closes a session, so that it becomes invalid, the server probably would respond with some error-indicating HTTP status code.

Thus requests would raise an error. See Errors and Exceptions:

All exceptions that Requests explicitly raises inherit from requests.exceptions.RequestException.

See the extended classes of RequestException.

Approach 1: implement open/close using try/except

Your code can catch such exceptions within a try/except-block. It depends on the server's API interface specification how it will signal a invalidated/closed session. This signal response should be evaluated in the except block.

Here we use session_was_closed(exception) function to evaluate the exception/response and Session.close() to close the session correctly before opening a new one.

import requests

# initially open a session object
s = requests.Session()

# execute requests continuously
while True:
    try:
        response = s.get(....)
        # process response
    except requests.exceptions.RequestException as e:
        if session_was_closed(e):
            s.close()  # close the session
            s = requests.Session()  # opens a new session
        else:
            # process non-session-related errors
    # wait for 5 seconds

Depending on the server response of your case, implement the method session_was_closed(exception).

Approach 2: automatically open/close using with

From Advanced Usage, Session Objects:

Sessions can also be used as context managers:

with requests.Session() as s:
    s.get('https://httpbin.org/cookies/set/sessioncookie/123456789')

This will make sure the session is closed as soon as the with block is exited, even if unhandled exceptions occurred.

hc_dev
  • 8,389
  • 1
  • 26
  • 38
  • My code will `get` every 5 seconds. For the approach two, it will open/close for every call. Will it be any performance concern? BTW, is there any example of `session_was_closed`? – ca9163d9 May 20 '22 at 00:37
  • @ca9163d9 Approach 2 will open a new session each time it enters the `with` block. So your polling (loop) should be moved inside the with-block to reuse the session and benefit from connection-pooling. For Approach 1, you can adjust the `session_was_closed` evaluation to your specification and expected server behavior. – hc_dev May 20 '22 at 15:36
1

I would flip the logic and add a try-except.

import requests
http = requests.Session()

while True:
    try:
        response = http.get(....)
    except requests.ConnectionException:
        http = requests.Session()
        continue
    # process respons
    # wait for 5 seconds  

See this answer for more info. I didn't test if the raised exception is that one, so please test it.

jolammi
  • 492
  • 3
  • 16