2013-02-02 11 views
12

के साथ पायथन "अनुरोध" का उपयोग करना पाइथन "अनुरोध" लाइब्रेरी वर्तमान में सभी क्रोध है, क्योंकि यह HTTP अनुरोध करने के लिए प्रदान किए जाने वाले सुंदर इंटरफ़ेस की वजह से है - लेकिन इसके नीचे संकेतों की कई परतें हैं - सत्र , HTTP एडाप्टर, और अंत में urllib3 के यांत्रिकी।मौजूदा सॉकेट कनेक्शन

जहां अबास्ट्रक्शन के इस ढेर में हस्तक्षेप करने का सही स्थान है, यदि मेरे पास पहले से खुली सॉकेट है, और उस सॉकेट के नीचे HTTP प्रतिक्रिया भेजने के लिए "अनुरोध" का उपयोग करना चाहते हैं और उत्तर वापस प्राप्त करना चाहते हैं?

किसी प्रकार के हस्तक्षेप (या अनुकूलन?) के बिना, स्टैक मेरे लिए एक नया टीसीपी/आईपी सॉकेट बनाने का प्रयास करेगा, लेकिन मेरे विशेष एप्लिकेशन में मेरा कोड तब तक नहीं बुलाया जाता है जब तक मेरी ओर से कनेक्शन पहले से स्थापित नहीं हो जाता , इसलिए यदि मैं अनुरोध की सुविधाओं का उपयोग करने में सक्षम होना चाहता हूं तो मुझे उस मौजूदा सॉकेट पर बात करने के लिए अनुरोधों को मनाने की आवश्यकता होगी।

अनुरोध पुस्तकालय:

http://pypi.python.org/pypi/requests

https://github.com/kennethreitz/requests

उत्तर

0

urllib3 पुस्तकालय के लिए सीधे जाओ, इसमें urllib3.connectionpool module में एक कनेक्शन पूल है।

आप पूल को प्रतिस्थापित कर सकते हैं या poolmanager module शायद हैकिंग करके इसे समायोजित कर सकते हैं।

8

निम्नलिखित कोड ncat -v -l 127.0.0.1 8000

समस्या

तथ्य उपयोग कर रहा है Git (विशेष रूप से requests.packages.urllib3.poolmanager.PoolManager._new_pool())

मैं इसे परीक्षण किया से अनुरोध की जरूरत है, कि कनेक्शन मानक पुस्तकालय से urllib3 द्वारा खोला नहीं है, लेकिन httplib द्वारा ।

import socket 
import requests 
from requests.adapters import HTTPAdapter 
from requests.packages.urllib3 import PoolManager, HTTPConnectionPool 

try: 
    from http.client import HTTPConnection 
except ImportError: 
    from httplib import HTTPConnection 


class MyAdapter(HTTPAdapter): 
    def init_poolmanager(self, connections, maxsize): 
     self.poolmanager = MyPoolManager(num_pools=connections, 
             maxsize=maxsize) 


class MyPoolManager(PoolManager): 
    def _new_pool(self, scheme, host, port): 
     # Important! 
     if scheme == 'http' and host == my_host and port == my_port: 
      return MyHTTPConnectionPool(host, port, **self.connection_pool_kw) 
     return super(PoolManager, self)._new_pool(self, scheme, host, port) 


class MyHTTPConnectionPool(HTTPConnectionPool): 
    def _new_conn(self): 
     self.num_connections += 1 
     return MyHTTPConnection(host=self.host, 
          port=self.port, 
          strict=self.strict) 


class MyHTTPConnection(HTTPConnection): 
    def connect(self): 
     """Connect to the host and port specified in __init__.""" 
     # Original 
     # self.sock = socket.create_connection((self.host, self.port), 
     #         self.timeout, self.source_address) 
     # Important! 
     self.sock = my_socket 
     if self._tunnel_host: 
      self._tunnel() 


if __name__ == '__main__': 
    import time 

    my_host = '127.0.0.1' 
    my_port = 8000 

    my_socket = socket.create_connection((my_host, my_port)) 
    time.sleep(4) 
    s = requests.Session() 
    s.mount('http://', MyAdapter()) 
    s.get('http://127.0.0.1:8000/foo') 

संपादित करें:

या प्रत्यक्ष connectionpool की monkeypatching:

class MyHTTPConnection(HTTPConnection): 
    def connect(self): 
     self.sock = my_socket 
     if self._tunnel_host: 
      self._tunnel() 

requests.packages.urllib3.connectionpool.HTTPConnection = MyHTTPConnection 

if __name__ == '__main__': 
    my_host = '127.0.0.1' 
    my_port = 8000 

    my_socket = socket.create_connection((my_host, my_port)) 
    requests.get('http://127.0.0.1:8000/foo') 
+0

यह monkeypatching मेरे लिए काम नहीं करता। मुझे यकीन नहीं है कि यह कभी काम नहीं करता है या यदि पिछले चार वर्षों में अनुरोध बदल गए हैं, लेकिन मेरी कक्षा का उपयोग नहीं किया जाता है (कम से कम, इसकी '__init__' और' कनेक्ट' विधियों को कभी नहीं कहा जाता है)। मैं अजगर 3.5 का उपयोग कर रहा हूं और 2.18.1 अनुरोध करता हूं। – Tom

संबंधित मुद्दे