##// END OF EJS Templates
use netifaces for faster IPython.utils.localinterfaces
use netifaces for faster IPython.utils.localinterfaces

File last commit:

r12830:6dcc15ee
r12830:6dcc15ee
Show More
localinterfaces.py
164 lines | 5.0 KiB | text/x-python | PythonLexer
MinRK
added localinterfaces to utils
r3143 """Simple utility for building a list of local IPs using the socket module.
This module defines two constants:
Bernardo B. Marques
remove all trailling spaces
r4872 LOCALHOST : The loopback interface, or the first interface that points to this
MinRK
added localinterfaces to utils
r3143 machine. It will *almost* always be '127.0.0.1'
LOCAL_IPS : A list of IP addresses, loopback first, that point to this machine.
MinRK
use netifaces for faster IPython.utils.localinterfaces
r12830 This will include LOCALHOST, PUBLIC_IPS, and aliases for all hosts,
such as '0.0.0.0'.
W. Trevor King
utils.localinterfaces: Add PUBLIC_IPS to consolidate socket logic...
r9250
PUBLIC_IPS : A list of public IP addresses that point to this machine.
Use these to tell remote clients where to find you.
MinRK
added localinterfaces to utils
r3143 """
#-----------------------------------------------------------------------------
Matthias BUSSONNIER
update copyright to 2011/20xx-2011...
r5390 # Copyright (C) 2010-2011 The IPython Development Team
MinRK
added localinterfaces to utils
r3143 #
# Distributed under the terms of the BSD License. The full license is in
# the file COPYING, distributed as part of this software.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
import socket
W. Trevor King
utils.localinterfaces: Uniquify LOCAL_IPS...
r9248 from .data import uniq_stable
MinRK
added localinterfaces to utils
r3143 #-----------------------------------------------------------------------------
# Code
#-----------------------------------------------------------------------------
LOCAL_IPS = []
W. Trevor King
utils.localinterfaces: Add PUBLIC_IPS to consolidate socket logic...
r9250 PUBLIC_IPS = []
MinRK
avoid executing code in utils.localinterfaces at import time...
r12591
MinRK
use netifaces for faster IPython.utils.localinterfaces
r12830 LOCALHOST = ''
MinRK
avoid executing code in utils.localinterfaces at import time...
r12591
def _only_once(f):
"""decorator to only run a function once"""
f.called = False
def wrapped():
if f.called:
return
ret = f()
f.called = True
return ret
return wrapped
def _requires_ips(f):
"""decorator to ensure load_ips has been run before f"""
def ips_loaded(*args, **kwargs):
_load_ips()
return f(*args, **kwargs)
return ips_loaded
MinRK
use netifaces for faster IPython.utils.localinterfaces
r12830 def _load_ips_netifaces():
"""load ip addresses with netifaces"""
import netifaces
global LOCALHOST
local_ips = []
public_ips = []
MinRK
avoid executing code in utils.localinterfaces at import time...
r12591
MinRK
use netifaces for faster IPython.utils.localinterfaces
r12830 # list of iface names, 'lo0', 'eth0', etc.
for iface in netifaces.interfaces():
# list of ipv4 addrinfo dicts
ipv4s = netifaces.ifaddresses(iface).get(netifaces.AF_INET, [])
for entry in ipv4s:
addr = entry.get('addr')
if not addr:
continue
if not (iface.startswith('lo') or addr.startswith('127.')):
public_ips.append(addr)
elif not LOCALHOST:
LOCALHOST = addr
local_ips.append(addr)
if not LOCALHOST:
# we never found a loopback interface (can this ever happen?), assume common default
LOCALHOST = '127.0.0.1'
local_ips.insert(0, LOCALHOST)
local_ips.extend(['0.0.0.0', ''])
LOCAL_IPS[:] = uniq_stable(local_ips)
PUBLIC_IPS[:] = uniq_stable(public_ips)
def _load_ips_gethostbyname():
"""load ip addresses with socket.gethostbyname_ex
This can be slow.
MinRK
avoid executing code in utils.localinterfaces at import time...
r12591 """
global LOCALHOST
try:
LOCAL_IPS[:] = socket.gethostbyname_ex('localhost')[2]
except socket.error:
MinRK
use netifaces for faster IPython.utils.localinterfaces
r12830 # assume common default
LOCAL_IPS[:] = ['127.0.0.1']
MinRK
avoid executing code in utils.localinterfaces at import time...
r12591
try:
hostname = socket.gethostname()
PUBLIC_IPS[:] = socket.gethostbyname_ex(hostname)[2]
# try hostname.local, in case hostname has been short-circuited to loopback
if not hostname.endswith('.local') and all(ip.startswith('127') for ip in PUBLIC_IPS):
PUBLIC_IPS[:] = socket.gethostbyname_ex(socket.gethostname() + '.local')[2]
except socket.error:
pass
finally:
PUBLIC_IPS[:] = uniq_stable(PUBLIC_IPS)
LOCAL_IPS.extend(PUBLIC_IPS)
# include all-interface aliases: 0.0.0.0 and ''
LOCAL_IPS.extend(['0.0.0.0', ''])
LOCAL_IPS[:] = uniq_stable(LOCAL_IPS)
LOCALHOST = LOCAL_IPS[0]
MinRK
use netifaces for faster IPython.utils.localinterfaces
r12830 def _load_ips_dumb():
"""Fallback in case of unexpected failure"""
global LOCALHOST
LOCALHOST = '127.0.0.1'
LOCAL_IPS[:] = [LOCALHOST, '0.0.0.0', '']
PUBLIC_IPS[:] = []
@_only_once
def _load_ips():
"""load the IPs that point to this machine
This function will only ever be called once.
It will use netifaces to do it quickly if available,
otherwise it will fallback on socket.gethostbyname_ex, which can be slow.
"""
try:
try:
_load_ips_netifaces()
except ImportError:
_load_ips_gethostbyname()
except Exception:
# unexpected error shouldn't crash, load dumb default values instead.
_load_ips_dumb()
MinRK
avoid executing code in utils.localinterfaces at import time...
r12591 @_requires_ips
def local_ips():
"""return the IP addresses that point to this machine"""
return LOCAL_IPS
@_requires_ips
def public_ips():
"""return the IP addresses for this machine that are visible to other machines"""
return PUBLIC_IPS
@_requires_ips
def localhost():
"""return ip for localhost (almost always 127.0.0.1)"""
return LOCALHOST
@_requires_ips
def is_local_ip(ip):
"""does `ip` point to this machine?"""
return ip in LOCAL_IPS
@_requires_ips
def is_public_ip(ip):
"""is `ip` a publicly visible address?"""
return ip in PUBLIC_IPS