title: Monkey patching sockets library to use a specifc network interface
body: <p>I have been trying to make requests to a website using the <code>requests</code> library but using different network interfaces. Following are a list of answers that I have tried to use but did not work.</p>
  
  <p>This <a href="https://stackoverflow.com/questions/48996494/send-http-request-through-specific-network-interface">answer</a> describes how to achieve what I want, but it uses <code>pycurl</code>. I could use <code>pycurl</code> but I have learned about this monkey patching thing and want to give it a try.</p>
  
  <p>This other <a href="https://stackoverflow.com/questions/12585317/requests-bind-to-an-ip/12590625#12590625">answer</a> seemed to work at first, since it does not raise any error. However, I monitored my network traffic using Wireshark and the packets were sent from my default interface. I tried to print messages inside the function <code>set_src_addr</code> defined by the author of the answer but the message did not show up. Therefore, I think it is patching a function that is never called. I get a HTTP 200 response, which should not occur since I have bound my socket to 127.0.0.1.</p>
  
  <pre><code>import socket
  
  real_create_conn = socket.create_connection
  
  def set_src_addr(*args):
      address, timeout = args[0], args[1]
      source_address = ('127.0.0.1', 0)
      return real_create_conn(address, timeout, source_address)
  
  socket.create_connection = set_src_addr
  
  import requests
  r = requests.get('http://www.google.com')
  r
  
  &lt;Response [200]&gt;
  </code></pre>
  
  <p>I have also tried this <a href="https://stackoverflow.com/questions/1150332/source-interface-with-python-and-urllib2/1150423#1150423">answer</a>. I can get two kind of errors using this method:</p>
  
  <pre><code>import socket                  
  true_socket = socket.socket    
  def bound_socket(*a, **k):     
      sock = true_socket(*a, **k)
      sock.bind(('127.0.0.1', 0))
      return sock                
  socket.socket = bound_socket   
  import requests
  </code></pre>
  
  <p>This will not allow me to create a socket and raise this <a href="https://gist.github.com/alexandredias3d/80a4ab0aea7aaa2db22d7605c325ec7f" rel="nofollow noreferrer">error</a>. I have also tried to make a variation of this answer which looks like this:</p>
  
  <pre><code>import requests                           
  import socket                             
  true_socket = socket.socket               
  def bound_socket(*a, **k):                
      sock = true_socket(*a, **k)           
      sock.bind(('192.168.0.10', 0))        
      print(sock)                           
      return sock                           
  socket.socket = bound_socket              
  r = requests.get('https://www.google.com')         
  </code></pre>
  
  <p>This also do not work and raises this <a href="https://gist.github.com/alexandredias3d/3ae3ae5fe726aeb0b65dcc0865b1b4fe" rel="nofollow noreferrer">error</a>.</p>
  
  <p>I have the following problem: I want to have each process sending requests through a specific network interface. I thought that since threads share global memory (including libraries), I should change my code to work with processes. Now, I want to apply a monkey patching solution somewhere, in a way that each process can use a different interface for communication. Am I missing something? Is this the best way to approach this problem?</p>
  
  <p><strong>Edit:</strong>
  I also would like to know if it is possible for different process to have different versions of the same library. If they are shared, how can I have different versions of a library in Python (one for each process)?</p>