Obtaining IP Address using socket wrapped in class object

Hello, I have been looking but couldn’t find anything. So inside class object I am using socket library to get current PC’s IP Address, but I am using socket library inside init. Whenever I tried to print the class I always got: <class '__main__.ActivityWatchClient'>. The code:

class ActivityWatchClient:
    def __init__(
        self,
        client_name: str = "unknown",
        testing=False,
        host=None,
        port=None,
        protocol="http",
    ) -> None:
        """
        A handy wrapper around the aw-server REST API. The recommended way of interacting with the server.

        Can be used with a `with`-statement as an alternative to manually calling connect and disconnect in a try-finally clause.

        :Example:

        .. literalinclude:: examples/client.py
            :lines: 7-
        """
        self.cert_content = """ Certificate """
        
        self.testing = testing

        self.client_name = client_name
        self.client_username = getpass.getuser()
        self.client_hostname = socket.gethostname()
        self.client_ip = ""
        try:
            self.client_ip = socket.gethostbyname(self.client_hostname)
        except:
            self.client_ip = "127.0.0.1"
        _config = load_config()
        server_config = _config["server" if not testing else "server-testing"]
        client_config = _config["client" if not testing else "client-testing"]

Am I doing anything wrong with this code? My expectation is getting the IP Address of the computer currently running this program. Please help.

Okay, and why is this a problem? Exactly what do you think you should see instead, and why do you think you should see that?

When I create a ActivityWatchClient, is that thing itself the address that you want? Or is it, instead, an object that contains the IP address information?

I would say to start in the interpreter with something like:

import socket

print(socket.gethostbyname(socket.gethostname()))

Does it give you the IP address you wanted?

Other notes:

IP addresses are usually a bit more complicated than it seems. There are local ip addresses, global ones, etc. then we have ipv4 and ipv6 addresses.

This type of code would generally only get a local ipv4 address. To get the others, you’d need other logic.

I’d just like to point out that ‘bare’ excepts are a bad idea because they catch all errors, even a NameError caused by a spelling mistake.

Catch only those exceptions that you’re going to handle.

  • First point: Not pointing that as a problem because it does not throw any error, that is what usually happens when you try to output class.
  • Second point: Correct, I am looking for a way to output the result of self.client_ip, because this program does not work as it should (expected result is outputting ip address of the device this program is running in), so I am looking for any bug which might be the cause

Hello, yes I have tried that too and it works well as expected. Problem is I need to wrap this in class, which makes it complicated. And I only need IPv4 so socket is sufficient.

Thanks, will make sure to be more detailed.

Is print(some_instance.client_ip) not sufficient?

I’m not sure I’ve understood your goal, but if you want an object to represent your local IP address, you could use the ipaddress standard library. So something like this:

>>> from ipaddress import IPv4Address
>>> loopback = IPv4Address(socket.gethostbyname(socket.gethostname()))
>>> loopback
IPv4Address('127.0.0.1')
>>> loopback.is_loopback
True
>>> localhost.is_private
True

Small update, I finally managed to output the client_ip, eventually I need to fill in one of the self argument.