1
1
from typing import Optional , Tuple , Union
2
+ import socket
2
3
3
4
from ray ._raylet import build_address as _build_address
4
5
from ray ._raylet import parse_address as _parse_address
6
+ from ray ._raylet import (
7
+ node_ip_address_from_perspective as _node_ip_address_from_perspective ,
8
+ )
9
+ from ray ._raylet import node_ip_from_hostname as _node_ip_from_hostname
10
+ from ray ._raylet import is_ipv6_ip as _is_ipv6_ip
5
11
6
12
7
13
def parse_address (address : str ) -> Optional [Tuple [str , str ]]:
@@ -29,6 +35,47 @@ def build_address(host: str, port: Union[int, str]) -> str:
29
35
return _build_address (host , port )
30
36
31
37
38
+ def node_ip_address_from_perspective (address : str = "" ) -> str :
39
+ """IP address by which the local node can be reached *from* the `address`.
40
+
41
+ If no address is given, defaults to public DNS servers for detection. For
42
+ performance, the result is cached when using the default address (empty string).
43
+ When a specific address is provided, detection is performed fresh every time.
44
+
45
+ Args:
46
+ address: The IP address and port of any known live service on the
47
+ network you care about.
48
+
49
+ Returns:
50
+ The IP address by which the local node can be reached from the address.
51
+ """
52
+ return _node_ip_address_from_perspective (address )
53
+
54
+
55
+ def node_ip_from_hostname () -> str :
56
+ """Get node IP address from hostname resolution without creating external connections.
57
+
58
+ This method uses hostname resolution to determine the local node's IP address,
59
+ avoiding socket creation that could trigger firewall popups on macOS/Windows.
60
+
61
+ Returns:
62
+ The IP address resolved from hostname, or empty string if resolution fails.
63
+ """
64
+ return _node_ip_from_hostname ()
65
+
66
+
67
+ def is_ipv6_ip (ip : str ) -> bool :
68
+ """Check if an IP string is IPv6 format.
69
+
70
+ Args:
71
+ ip: The IP address string to check (must be pure IP, no port).
72
+
73
+ Returns:
74
+ True if the IP is IPv6, False if IPv4.
75
+ """
76
+ return _is_ipv6_ip (ip )
77
+
78
+
32
79
def is_localhost (host : str ) -> bool :
33
80
"""Check if the given host string represents a localhost address.
34
81
@@ -39,3 +86,29 @@ def is_localhost(host: str) -> bool:
39
86
True if the host is a localhost address, False otherwise.
40
87
"""
41
88
return host in ("localhost" , "127.0.0.1" , "::1" )
89
+
90
+
91
+ def create_socket (socket_type : int = socket .SOCK_STREAM ) -> socket .socket :
92
+ """Create a Python socket object with the appropriate family based on the node IP.
93
+
94
+ This function automatically gets the node IP address and creates a socket
95
+ with the correct family (AF_INET for IPv4, AF_INET6 for IPv6).
96
+
97
+ Args:
98
+ socket_type: The socket type (socket.SOCK_STREAM, socket.SOCK_DGRAM, etc.).
99
+
100
+ Returns:
101
+ A Python socket.socket object configured for the node's IP family.
102
+
103
+ Example:
104
+ # Create a TCP socket for the current node
105
+ sock = create_socket()
106
+
107
+ # Create a UDP socket for the current node
108
+ sock = create_socket(socket.SOCK_DGRAM)
109
+ """
110
+ node_ip = node_ip_address_from_perspective ()
111
+ family = socket .AF_INET6 if is_ipv6_ip (node_ip ) else socket .AF_INET
112
+
113
+ # Create socket directly with Python socket API
114
+ return socket .socket (family , socket_type )
0 commit comments