import socket import struct from typing import Optional from urllib.parse import urlparse def is_loopback(address): host: Optional[str] = None try: parsed_url = urlparse(address) host = parsed_url.hostname except ValueError: return False # url is not even a url loopback_checker = { socket.AF_INET: lambda x: struct.unpack("!I", socket.inet_aton(x))[0] >> (32 - 8) == 127, socket.AF_INET6: lambda x: x == "::1", } for family in (socket.AF_INET, socket.AF_INET6): try: r = socket.getaddrinfo(host, None, family, socket.SOCK_STREAM) except socket.gaierror: continue for family, _, _, _, sockaddr in r: if loopback_checker[family](sockaddr[0]): return True if host in ("localhost",): return True return False