soroushamdg
soroushamdg

Reputation: 211

How to get local ip address python?

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

Answers (4)

Horst Schmid
Horst Schmid

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

goulashsoup
goulashsoup

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

Jaide Ambrosio
Jaide Ambrosio

Reputation: 11

Modified as print("IP Address:",socket.gethostbyname(hostname)) work for me. Using Windows 10.

Upvotes: 1

Mohammed
Mohammed

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

Related Questions