ipaddress
import ipaddress The ipaddress module provides classes for working with IPv4 and IPv6 addresses, networks, and interfaces. It lets you parse strings into address objects, perform arithmetic, check address types (private, multicast, loopback), and work with network ranges including subnets and supernets.
Factory Functions
The module provides three convenience functions that automatically detect whether you’re working with IPv4 or IPv6 and return the appropriate object type.
ip_address()
Returns an IPv4Address or IPv6Address object depending on the input.
import ipaddress
# Parse a string
ip = ipaddress.ip_address("192.168.1.1")
print(ip) # 192.168.1.1
print(type(ip)) # <class 'ipaddress.IPv4Address'>
# Parse an integer
ip = ipaddress.ip_address(3232235777)
print(ip) # 192.168.1.1
# IPv6 example
ip = ipaddress.ip_address("2001:db8::1")
print(type(ip)) # <class 'ipaddress.IPv6Address'>
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
address | str, int, or bytes | — | An IPv4 or IPv6 address string, integer, or packed bytes |
Returns: IPv4Address or IPv6Address
Raises: AddressValueError if the address is invalid
ip_network()
Returns an IPv4Network or IPv6Network object representing a network range.
import ipaddress
# Parse a CIDR range
network = ipaddress.ip_network("192.168.0.0/24")
print(network) # 192.168.0.0/24
print(network.num_addresses) # 256
# Check if an IP is in the network
ip = ipaddress.ip_address("192.168.0.50")
print(ip in network) # True
# Get network address and broadcast
print(network.network_address) # 192.168.0.0
print(network.broadcast_address) # 192.168.0.255
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
address | str, int, or bytes | — | Network address with optional prefix (e.g., ‘192.168.0.0/24’) |
strict | bool | False | If True, raises ValueError when host bits are set |
Returns: IPv4Network or IPv6Network
ip_interface()
Returns an IPv4Interface or IPv6Interface object representing an address with an associated network.
import ipaddress
interface = ipaddress.ip_interface("192.168.1.100/24")
print(interface) # 192.168.1.100/24
print(interface.ip) # 192.168.1.100
print(interface.network) # 192.168.1.0/24
print(interface.netmask) # 255.255.255.0
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
address | str, int, or bytes | — | IP address with network prefix |
Returns: IPv4Interface or IPv6Interface
Address Classes
IPv4Address
Represents a single IPv4 address.
import ipaddress
ip = ipaddress.IPv4Address("192.168.1.1")
# Check address type
print(ip.is_private) # True (192.168.0.0/16)
print(ip.is_loopback) # True (127.0.0.0/8)
print(ip.is_multicast) # False
print(ip.is_global) # False
print(ip.is_link_local) # False (169.254.0.0/16)
# Arithmetic
ip_next = ip + 1
print(ip_next) # 192.168.1.2
ip_diff = ipaddress.IPv4Address("192.168.1.10") - ip
print(ip_diff) # 9
# Binary representation
print(ip.packed) # b'\xc0\xa8\x01\x01'
Key attributes:
| Attribute | Type | Description |
|---|---|---|
packed | bytes | Binary representation (4 bytes) |
is_private | bool | True if address is in private range |
is_global | bool | True if address is globally reachable |
is_loopback | bool | True if 127.0.0.0/8 |
is_multicast | bool | True if in multicast range |
is_link_local | bool | True if 169.254.0.0/16 |
is_reserved | bool | True if 240.0.0.0/4 |
version | int | Always 4 |
IPv6Address
Represents a single IPv6 address.
import ipaddress
ip = ipaddress.IPv6Address("2001:db8::1")
print(ip.version) # 6
print(ip.is_loopback) # False
print(ip.is_multicast) # False
# IPv4-mapped IPv6 address
ip = ipaddress.IPv6Address("::ffff:192.168.1.1")
print(ip.ipv4_mapped) # (192, 168, 1, 1)
print(ip.is_ipv4_mapped) # True
Key attributes:
| Attribute | Type | Description |
|---|---|---|
packed | bytes | Binary representation (16 bytes) |
ipv4_mapped | tuple or None | Embedded IPv4 address if IPv4-mapped |
zone_id | str or None | Zone ID for scoped addresses |
version | int | Always 6 |
Network Classes
IPv4Network
Represents an IPv4 network range.
import ipaddress
network = ipaddress.IPv4Network("192.168.0.0/24")
# Iterate over all hosts (excludes network and broadcast)
for host in network.hosts():
print(host)
# Get supernet (smaller prefix = larger network)
supernet = network.supernet()
print(supernet) # 192.168.0.0/23
# Get subnets (larger prefix = smaller networks)
for subnet in network.subnets(prefixlen_diff=2):
print(subnet)
# 192.168.0.0/26
# 192.168.0.64/26
# 192.168.0.128/26
# 192.168.0.192/26
# Network contains another network
print(network.overlaps(ipaddress.IPv4Network("192.168.1.0/24"))) # False
IPv6Network
Same interface as IPv4Network but for IPv6 addresses.
import ipaddress
network = ipaddress.IPv6Network("2001:db8::/48")
print(network.num_addresses) # 2**80 addresses
for host in network.hosts():
print(host)
break # Only first few for demonstration
Common Patterns
Validating user input
import ipaddress
def validate_ip(ip_str):
try:
ip = ipaddress.ip_address(ip_str)
return True, f"Valid {ip.version} address: {ip}"
except ValueError as e:
return False, str(e)
print(validate_ip("192.168.1.1")) # (True, 'Valid 4 address: 192.168.1.1')
print(validate_ip("256.1.1.1")) # (False, "'256.1.1.1' does not appear to be an IPv4 or IPv6 address")
print(validate_ip("not.an.ip")) # (False, ...)
Finding private subnets
import ipaddress
ips = [
"10.0.0.1",
"172.16.0.1",
"192.168.1.1",
"8.8.8.8",
"203.0.113.1",
]
private = [ip for ip in ips if ipaddress.ip_address(ip).is_private]
print(private) # ['10.0.0.1', '172.16.0.1', '192.168.1.1']
CIDR validation and parsing
import ipaddress
def parse_cidr(cidr_str):
try:
network = ipaddress.ip_network(cidr_str, strict=False)
return True, network
except ValueError as e:
return False, None
# Valid CIDR
valid, net = parse_cidr("192.168.0.0/24")
print(f"Network: {net}, Hosts: {net.num_addresses - 2}")
# Invalid CIDR (invalid prefix length)
valid, net = parse_cidr("192.168.0.1/24")
print(valid) # False
# Accepts host bits with strict=False
valid, net = parse_cidr("192.168.0.1/24")
print(valid, net) # True 192.168.0.0/24
Errors
The module raises two custom exceptions:
| Exception | When raised |
|---|---|
AddressValueError | Invalid IP address format |
NetmaskValueError | Invalid netmask value |
import ipaddress
try:
ipaddress.ip_address("999.999.999.999")
except ipaddress.AddressValueError as e:
print(f"Invalid IP: {e}")
try:
ipaddress.ip_network("192.168.1.0/33")
except ipaddress.NetmaskValueError as e:
print(f"Invalid mask: {e}")