Issue
If I create a requests.Session()
and use it for several requests, if one of those requests were to throw an exception like this:
requests.exceptions.ConnectionError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response',))
Assuming I caught the exception and continued executing, what would happen if I used the session again? My understanding is that the object caches a TCP connection that can get used by multiple requests on the session, which I guess would get lost when this error occurs. Does the Session
object try to reestablish the connection automatically, or would I need to do that in the exception handler? If I do, is there a way to tell the Session
to try reestablishing the connection if it happens to fail?
Here is a code segment that would cause the above to happen:
sess = requests.Session()
try:
response = sess.get('http://someapi.com')
response = sess.get('http://someapi.com') # throws requests.exceptions.ConnectionError
except requests.exceptions.ConnectionError:
response = sess.get('http://someapi.com') # what happens here?
Solution
I was able to verify using a minimal reproducer that the session will indeed try to connect again on the event of a remote disconnect the next time a request is made.
The reproducer consists of two files. server.py
is a simple webserver that asks for command line input whenever it gets a GET request. Given 'y', it sends a response, and given 'n' it does not. test.py
implements similar code to the example in the question. By inputting the sequence 'y', 'n', 'y' into the server, it can be shown that the session in test.py
will succeed on the final request.
server.py (based on https://pythonbasics.org/webserver/)
# Python 3 server example
from http.server import BaseHTTPRequestHandler, HTTPServer
hostName = "localhost"
serverPort = 8080
class MyServer(BaseHTTPRequestHandler):
def do_GET(self):
userin = input('y/n:')
if userin == 'y':
self.send_response(200)
self.send_header("Content-type", "text/plain")
self.end_headers()
self.wfile.write(bytes("response text", "utf-8"))
if __name__ == "__main__":
webServer = HTTPServer((hostName, serverPort), MyServer)
print("Server started http://%s:%s" % (hostName, serverPort))
try:
webServer.serve_forever()
except KeyboardInterrupt:
pass
webServer.server_close()
print("Server stopped.")
test.py
import requests
sess = requests.Session()
try:
print(sess.get('http://localhost:8080'))
print(sess.get('http://localhost:8080'))
except Exception as e:
print(e)
print(sess.get('http://localhost:8080'))
server.py output
Server started http://localhost:8080
y/n:y
127.0.0.1 - - [07/Oct/2022 11:43:45] "GET / HTTP/1.1" 200 -
y/n:n
y/n:y
127.0.0.1 - - [07/Oct/2022 11:43:50] "GET / HTTP/1.1" 200 -
test.py output
<Response [200]>
('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
<Response [200]>
Answered By - Rob Streeting
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.