2013-03-01 17 views
5

Napisałem bardzo prostego klienta dla odpoczynku API przy użyciu doskonałej biblioteki żądań dla Pythona. Wszystko działa wspaniale dzięki uruchomieniu klienta przez loadbalancer, który wykrywa bezczynne połączenia TCP i zabija je. Chciałbym, aby mój klient używał różnych opcji utrzymywania żywych tcp niż domyślne na mojej platformie (linux). Ale nie widzę łatwego sposobu poinformowania biblioteki gniazd, że chciałbym wybrać niektóre domyślne opcje dla nowych gniazd.Czy można zastąpić domyślne opcje gniazd w żądaniach?

Bezpośrednio przy użyciu socket.create_connection można to łatwo zrobić przy użyciu dekoratora, ale nie mam pojęcia, jak udostępnić to udekorowane połączenie, gdy rozmowa zostanie pogrzebana w bibliotece innej firmy, tak jak w przypadku z prośbami.

góry dzięki

+0

Niech zgadnę: Azure? – Dacav

Odpowiedz

3

requests używa urllib3, który korzysta z biblioteki standardowej za http.client (lub httplib, na 2.x), który wywołuje socket.create_connection, wszystko bez nigdzie zahaczyć rzeczy.

Musisz albo rozwidlić jedną z tych bibliotek, albo monkeypatch to w locie.

Najprostszym miejsce do tego to chyba w http.client.connect, ponieważ to jest trywialne otoki wokół socket.create_connection, które mogą być łatwo zamienione na:

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

Jeśli jesteś na 2.x, to prawdopodobnie tak proste, jak po prostu używając powyższego httplib zamiast http.client, ale możesz to sprawdzić.

+0

Niesamowite rozwiązanie, nie zdawałem sobie sprawy, że podział modułów działał w ten sposób. –

+1

Można to teraz zrobić poprzez 'HTTPConnection.socket_options' lub' HTTPConnection.default_socket_options' od 'urllib3' 1.8.3. – univerio

5

Nowsze wersje urllib3 (od wersji 1.8.3, wydana 2014-06-23) obsługują opcje gniazd gniazd.

Można ustawić te opcje z requests (od 2.4.0, wydany 2014-08-29) poprzez utworzenie niestandardowego adaptera:

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) 

Następnie można zamontować ten adapter do sesji, które wymagają niestandardowego gniazda Opcje (np ustawienie SO_KEEPALIVE):

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

Czy to jest żądanie.Session()? –

+0

@JasonHeiss Te są wymienne. – univerio

Powiązane problemy