Reputation: 211
There's a code I found in internet that says it gives my machines local network IP address:
hostname = socket.gethostname()
local_ip = socket.gethostbyname(hostname)
but the IP it returns is 192.168.94.2 but my IP address in WIFI network is actually 192.168.1.107 How can I only get wifi network local IP address with only python? I want it to work for windows,linux and macos.
Upvotes: 5
Views: 19168
Reputation: 314
On my Raspberry (bookworm) the socket.getfqdn()
returns only the pure host name, not the fully qualified name! And with that the socket.gethostbyname_ex
returns only 127.0.0.1.
According to socket.getfqdn() and socket.gethostname() are giving Different IP addresses when using socket.gethostname the socket.getfqdn() is reading the file /etc/hosts.
The shell command hostname -A
returns two times the FQDN on my Raspberry.
The shell command hostname -I
returns all IP addresses, starting with the IPv4 (if any!?), followed by IPv6 addresses:
y = subprocess.run(['/usr/bin/hostname', '-I'], capture_output=True)
ipAddrs = y.stdout.split()
ipv4 = ipAddrs[0]
I am not sure, whether the last address ipAddrs[-1]
is always a link local address fd00:... or that's only so in my case.
On other systems the hostname -I
may be not available, e.g. Synology NAS DSM 7.2.
Upvotes: 0
Reputation: 3116
To my research we HAVE TO use OS shell commands to get it right.
import os, subprocess, platform, ipaddress
def run_shell_command(command, capture_output = False):
print(f"$ {command}")
return subprocess.run(command, shell=True, capture_output=capture_output, text=capture_output) # 'shell=True' => Use built-in shell, '/bin/sh' on Linux and Mac, 'cmd.exe' on Windows.
def get_local_ipv4():
local_ipv4 = None
operating_system_kind = platform.system()
if operating_system_kind == 'Darwin':
local_ipv4 = run_shell_command('ipconfig getifaddr en0', True).stdout.strip()
elif operating_system_kind == 'Windows':
for line in run_shell_command('netsh ip show address | findstr "IP Address"', True).stdout.split(os.linesep):
local_ipv4_or_empty = line.removeprefix('IP Address:').strip()
if local_ipv4_or_empty:
local_ipv4 = local_ipv4_or_empty
break
else: # Linux
local_ipv4 = run_shell_command("hostname -I | awk '{print $1}'", True).stdout.strip()
try:
ipaddress.IPv4Address(local_ipv4)
except ipaddress.AddressValueError:
raise Exception("Could not get local network IPv4 address for Expo Fronted")
if local_ipv4.startswith("127.0."):
raise Exception(f"Could not get correct local network IPv4 address for Expo Fronted, got {local_ipv4}")
return local_ipv4
local_ipv4 = get_local_ipv4()
Upvotes: 1
Reputation: 11
Modified as
print("IP Address:",socket.gethostbyname(hostname))
work for me. Using Windows 10.
Upvotes: 1
Reputation: 152
You can use this code:
import socket
hostname = socket.getfqdn()
print("IP Address:",socket.gethostbyname_ex(hostname)[2][1])
or this to get public ip:
import requests
import json
print(json.loads(requests.get("https://ip.seeip.org/jsonip?").text)["ip"])
Upvotes: 10