Is it possible to override the default socket settings in requests?

I wrote a very simple client for the remainder API, using the excellent python request library. Everything works great. I run the client through a loadbalancer that checks for idle tcp connections and kills them. I would like my client to use some different tcp keep alive options than the default settings on my platform (linux). But I don’t see an easy way to tell the socket library that I would like to select some default options for new sockets.

Using socket.create_connection directly is quite simple to do with the decorator, but I have no idea how to make this decorated call available when the actual call is buried in some third-party library, as is the case with requests.

early

+5
source share
2 answers

requestsuses urllib3, which uses the standard library http.client(or httplib, for 2.x), which calls socket.create_connection, without any need to intercept things.

So, you have to either unlock one of these libraries, or neutralize it on the fly.

The easiest place for this is probably in http.client.connect, since there is a trivial wrapper around socket.create_connectionthat can be easily changed

orig_connect = http.client.HTTPConnection.connect
def monkey_connect(self):
    orig_connect(self)
    self.sock.setsockopt(…)
http.client.HTTPConnection.connect = monkey_connect

2.x, , , , httplib http.client , .

+3

urllib3 ( 1.8.3, 2014-06-23) .

requests ( 2.4.0, 2014-08-29), :

class HTTPAdapterWithSocketOptions(requests.adapters.HTTPAdapter):
    def __init__(self, *args, **kwargs):
        self.socket_options = kwargs.pop("socket_options", None)
        super(HTTPAdapterWithSocketOptions, self).__init__(*args, **kwargs)

    def init_poolmanager(self, *args, **kwargs):
        if self.socket_options is not None:
            kwargs["socket_options"] = self.socket_options
        super(HTTPAdapterWithSocketOptions, self).init_poolmanager(*args, **kwargs)

, (, SO_KEEPALIVE):

adapter = HTTPAdapterWithSocketOptions(socket_options=[(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)])
s = requests.session()
s.mount("http://", adapter)
s.mount("https://", adapter)
+5

All Articles