Skip to content

Commit d1fd333

Browse files
authored
Merge pull request #97 from openscilab/myip_wtf
New API: `myip.wtf`
2 parents c52cfa0 + ed6294d commit d1fd333

File tree

7 files changed

+89
-3
lines changed

7 files changed

+89
-3
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
77
## [Unreleased]
88
### Added
99
- Support [wtfismyip.com](https://wtfismyip.com/json) IPv6 API
10+
- Support [myip.wtf](https://myip.wtf/) IPv6 API
11+
- Support [myip.wtf](https://myip.wtf/) IPv4 API
1012
### Changed
1113
- `README.md` updated
1214
## [0.7] - 2025-12-09

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ Public IP and Location Info:
187187

188188
#### IPv4 API
189189

190-
ℹ️ `ipv4-api` valid choices: [`auto-safe`, `auto`, `ip-api.com`, `ipinfo.io`, `ip.sb`, `ident.me`, `tnedi.me`, `ipapi.co`, `ipleak.net`, `my-ip.io`, `ifconfig.co`, `reallyfreegeoip.org`, `freeipapi.com`, `myip.la`, `ipquery.io`, `ipwho.is`, `wtfismyip.com`]
190+
ℹ️ `ipv4-api` valid choices: [`auto-safe`, `auto`, `ip-api.com`, `ipinfo.io`, `ip.sb`, `ident.me`, `tnedi.me`, `ipapi.co`, `ipleak.net`, `my-ip.io`, `ifconfig.co`, `reallyfreegeoip.org`, `freeipapi.com`, `myip.la`, `ipquery.io`, `ipwho.is`, `wtfismyip.com`, `myip.wtf`]
191191

192192
ℹ️ The default value: `auto-safe`
193193

@@ -230,7 +230,7 @@ Public IP and Location Info:
230230

231231
#### IPv6 API
232232

233-
ℹ️ `ipv6-api` valid choices: [`auto-safe`, `auto`, `ip.sb`, `ident.me`, `tnedi.me`, `ipleak.net`, `my-ip.io`, `ifconfig.co`, `reallyfreegeoip.org`, `myip.la`, `freeipapi.com`, `wtfismyip.com`]
233+
ℹ️ `ipv6-api` valid choices: [`auto-safe`, `auto`, `ip.sb`, `ident.me`, `tnedi.me`, `ipleak.net`, `my-ip.io`, `ifconfig.co`, `reallyfreegeoip.org`, `myip.la`, `freeipapi.com`, `wtfismyip.com`, `myip.wtf`]
234234

235235
ℹ️ The default value: `auto-safe`
236236

ipspot/ipv4.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,34 @@ def _wtfismyip_com_ipv4(geo: bool, timeout: Union[float, Tuple[float, float]]
466466
return {"status": False, "error": str(e)}
467467

468468

469+
def _myip_wtf_ipv4(geo: bool, timeout: Union[float, Tuple[float, float]]
470+
) -> Dict[str, Union[bool, Dict[str, Union[str, float]], str]]:
471+
"""
472+
Get public IP and geolocation using myip.wtf.
473+
474+
:param geo: geolocation flag
475+
:param timeout: timeout value for API
476+
"""
477+
try:
478+
data = _get_json_standard(url="https://json.ipv4.myip.wtf", timeout=timeout)
479+
result = {"status": True, "data": {"ip": data["YourFuckingIPAddress"], "api": "myip.wtf"}}
480+
if geo:
481+
geo_data = {
482+
"city": data.get("YourFuckingCity"),
483+
"region": None,
484+
"country": data.get("YourFuckingCountry"),
485+
"country_code": data.get("YourFuckingCountryCode"),
486+
"latitude": None,
487+
"longitude": None,
488+
"organization": data.get("YourFuckingISP"),
489+
"timezone": None
490+
}
491+
result["data"].update(geo_data)
492+
return result
493+
except Exception as e:
494+
return {"status": False, "error": str(e)}
495+
496+
469497
IPV4_API_MAP = {
470498
IPv4API.IFCONFIG_CO: {
471499
"thread_safe": False,
@@ -542,6 +570,11 @@ def _wtfismyip_com_ipv4(geo: bool, timeout: Union[float, Tuple[float, float]]
542570
"geo": True,
543571
"function": _wtfismyip_com_ipv4
544572
},
573+
IPv4API.MYIP_WTF: {
574+
"thread_safe": True,
575+
"geo": True,
576+
"function": _myip_wtf_ipv4
577+
},
545578
}
546579

547580

ipspot/ipv6.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,34 @@ def _wtfismyip_com_ipv6(geo: bool, timeout: Union[float, Tuple[float, float]]
320320
return {"status": False, "error": str(e)}
321321

322322

323+
def _myip_wtf_ipv6(geo: bool, timeout: Union[float, Tuple[float, float]]
324+
) -> Dict[str, Union[bool, Dict[str, Union[str, float]], str]]:
325+
"""
326+
Get public IP and geolocation using myip.wtf.
327+
328+
:param geo: geolocation flag
329+
:param timeout: timeout value for API
330+
"""
331+
try:
332+
data = _get_json_standard(url="https://json.ipv6.myip.wtf", timeout=timeout)
333+
result = {"status": True, "data": {"ip": data["YourFuckingIPAddress"], "api": "myip.wtf"}}
334+
if geo:
335+
geo_data = {
336+
"city": data.get("YourFuckingCity"),
337+
"region": None,
338+
"country": data.get("YourFuckingCountry"),
339+
"country_code": data.get("YourFuckingCountryCode"),
340+
"latitude": None,
341+
"longitude": None,
342+
"organization": data.get("YourFuckingISP"),
343+
"timezone": None
344+
}
345+
result["data"].update(geo_data)
346+
return result
347+
except Exception as e:
348+
return {"status": False, "error": str(e)}
349+
350+
323351
IPV6_API_MAP = {
324352
IPv6API.IP_SB: {
325353
"thread_safe": True,
@@ -371,6 +399,11 @@ def _wtfismyip_com_ipv6(geo: bool, timeout: Union[float, Tuple[float, float]]
371399
"geo": True,
372400
"function": _wtfismyip_com_ipv6
373401
},
402+
IPv6API.MYIP_WTF: {
403+
"thread_safe": True,
404+
"geo": True,
405+
"function": _myip_wtf_ipv6
406+
},
374407
}
375408

376409

ipspot/params.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class IPv4API(Enum):
3838
IPQUERY_IO = "ipquery.io"
3939
IPWHO_IS = "ipwho.is"
4040
WTFISMYIP_COM = "wtfismyip.com"
41+
MYIP_WTF = "myip.wtf"
4142

4243

4344
class IPv6API(Enum):
@@ -55,6 +56,7 @@ class IPv6API(Enum):
5556
MYIP_LA = "myip.la"
5657
FREEIPAPI_COM = "freeipapi.com"
5758
WTFISMYIP_COM = "wtfismyip.com"
59+
MYIP_WTF = "myip.wtf"
5860

5961

6062
PARAMETERS_NAME_MAP = {

tests/test_ipv4_api.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,11 @@ def test_public_ipv4_wtfismyip_com_success():
137137
assert is_ipv4(result["data"]["ip"])
138138
assert set(result["data"].keys()) == DATA_ITEMS
139139
assert result["data"]["api"] == "wtfismyip.com"
140+
141+
142+
def test_public_ipv4_myip_wtf_success():
143+
result = get_public_ipv4(api=IPv4API.MYIP_WTF, geo=True, timeout=40, max_retries=4, retry_delay=90, backoff_factor=1.1)
144+
assert result["status"]
145+
assert is_ipv4(result["data"]["ip"])
146+
assert set(result["data"].keys()) == DATA_ITEMS
147+
assert result["data"]["api"] == "myip.wtf"

tests/test_ipv6_api.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,12 @@ def test_public_ipv6_auto_safe_success():
9595
result = get_public_ipv6(api=IPv6API.AUTO_SAFE, geo=True, timeout=40, max_retries=4, retry_delay=90, backoff_factor=1.1)
9696
assert result["status"]
9797
assert is_ipv6(result["data"]["ip"])
98-
assert set(result["data"].keys()) == DATA_ITEMS
98+
assert set(result["data"].keys()) == DATA_ITEMS
99+
100+
101+
def test_public_ipv6_myip_wtf_success():
102+
result = get_public_ipv6(api=IPv6API.MYIP_WTF, geo=True, timeout=40, max_retries=4, retry_delay=90, backoff_factor=1.1)
103+
assert result["status"]
104+
assert is_ipv6(result["data"]["ip"])
105+
assert set(result["data"].keys()) == DATA_ITEMS
106+
assert result["data"]["api"] == "myip.wtf"

0 commit comments

Comments
 (0)