How to Get Hostname and IP Address in Python
A machine typically has multiple IP addresses: loopback (127.0.0.1), local network (LAN), and public internet (WAN). Python's socket module provides the tools to retrieve each.
Getting the Hostname
The hostname is the human-readable name identifying your computer on the network:
import socket
hostname = socket.gethostname()
print(f"Hostname: {hostname}")
# Example: "my-laptop" or "server-01"
Getting the Local IP Address (LAN)
Your local network address (typically 192.168.x.x or 10.x.x.x) requires the "UDP trick" for reliable detection:
import socket
def get_local_ip():
"""Get local IP address using UDP socket trick."""
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
# Connect to external address (no data sent)
s.connect(('8.8.8.8', 80))
return s.getsockname()[0]
except Exception:
return '127.0.0.1'
finally:
s.close()
print(f"Local IP: {get_local_ip()}")
# Example: "192.168.1.105"
This method works by asking the OS which interface would route traffic to an external address, without actually sending any data.
The common approach socket.gethostbyname(socket.gethostname()) often returns 127.0.0.1 on Linux systems. The UDP trick is more reliable across platforms.
Getting the Public IP Address (WAN)
Your public IP is assigned by your ISP and requires querying an external service:
import urllib.request
def get_public_ip():
"""Get public IP address from external service."""
try:
response = urllib.request.urlopen('https://api.ipify.org', timeout=5)
return response.read().decode('utf-8')
except Exception as e:
return f"Error: {e}"
print(f"Public IP: {get_public_ip()}")
# Example: "203.0.113.42"
Using the requests library for more control:
import requests
def get_public_ip():
"""Get public IP with detailed info."""
try:
response = requests.get('https://ipapi.co/json/', timeout=5)
data = response.json()
return {
'ip': data.get('ip'),
'city': data.get('city'),
'country': data.get('country_name'),
'isp': data.get('org')
}
except requests.RequestException as e:
return None
info = get_public_ip()
print(info)
# {'ip': '203.0.113.42', 'city': 'New York', 'country': 'United States', 'isp': 'Example ISP'}
Getting All Network Interfaces
List all IP addresses on all network interfaces:
import socket
def get_all_ips():
"""Get all IP addresses for this host."""
hostname = socket.gethostname()
try:
# Get all address info
addresses = socket.getaddrinfo(hostname, None, socket.AF_INET)
return list(set(addr[4][0] for addr in addresses))
except socket.gaierror:
return ['127.0.0.1']
print(get_all_ips())
# ['192.168.1.105', '127.0.0.1']
For detailed interface information, use the netifaces library:
import netifaces
def get_interface_details():
"""Get detailed info for all network interfaces."""
interfaces = {}
for iface in netifaces.interfaces():
addrs = netifaces.ifaddresses(iface)
# Get IPv4 addresses
if netifaces.AF_INET in addrs:
interfaces[iface] = {
'ipv4': addrs[netifaces.AF_INET][0].get('addr'),
'netmask': addrs[netifaces.AF_INET][0].get('netmask')
}
return interfaces
print(get_interface_details())
# {'eth0': {'ipv4': '192.168.1.105', 'netmask': '255.255.255.0'},
# 'lo': {'ipv4': '127.0.0.1', 'netmask': '255.0.0.0'}}
Complete Network Information Function
Combine all methods into a comprehensive function:
import socket
import urllib.request
def get_network_info():
"""Get comprehensive network information."""
info = {}
# Hostname
info['hostname'] = socket.gethostname()
# Local IP (UDP trick)
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('8.8.8.8', 80))
info['local_ip'] = s.getsockname()[0]
s.close()
except Exception:
info['local_ip'] = '127.0.0.1'
# Public IP
try:
response = urllib.request.urlopen('https://api.ipify.org', timeout=5)
info['public_ip'] = response.read().decode('utf-8')
except Exception:
info['public_ip'] = 'Unavailable'
return info
print(get_network_info())
# {'hostname': 'my-laptop', 'local_ip': '192.168.1.105', 'public_ip': '203.0.113.42'}
Public IP detection requires internet access and relies on external services. Always include timeout and error handling for production code.
Checking If IP Is Local or Public
import ipaddress
def is_private_ip(ip_string):
"""Check if IP address is private (local network)."""
try:
ip = ipaddress.ip_address(ip_string)
return ip.is_private
except ValueError:
return False
print(is_private_ip('192.168.1.1')) # True
print(is_private_ip('10.0.0.1')) # True
print(is_private_ip('8.8.8.8')) # False
print(is_private_ip('172.16.0.1')) # True
Quick Reference
| Goal | Method | Example Result |
|---|---|---|
| Hostname | socket.gethostname() | "my-laptop" |
| Local IP | UDP trick to 8.8.8.8 | "192.168.1.105" |
| Public IP | External API call | "203.0.113.42" |
| All IPs | socket.getaddrinfo() | List of addresses |
Summary
- Use
socket.gethostname()for the machine name. - For local IP, the UDP socket trick connecting to
8.8.8.8is the most reliable cross-platform method. - Public IP requires querying an external service like
api.ipify.org. - Avoid
socket.gethostbyname(hostname)as it often returns loopback on Linux systems.