Skip to content

Commit 946efde

Browse files
authored
New IPv4 API freeipapi.com (#49)
* add `FREEIPAPI_COM` to `IPv4API` * add `_freeipapi_com_ipv4` function * tests added * `CHANGELOG.md` updated * `README.md` updated * use `_get_json_ipv4_forced`
1 parent cc5f4c5 commit 946efde

File tree

5 files changed

+56
-1
lines changed

5 files changed

+56
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1111
- Support [my-ip.io](https://www.my-ip.io/)
1212
- Support [ifconfig.co](https://ifconfig.co/json)
1313
- Support [reallyfreegeoip.org](https://reallyfreegeoip.org/json/)
14+
- Support [freeipapi.com](https://freeipapi.com/api/json/)
1415
- `AUTO_SAFE` mode
1516
- `_get_json_standard` function
1617
- `_get_json_ipv4_forced` function

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ Public IP and Location Info:
147147

148148
#### IPv4 API
149149

150-
ℹ️ `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`]
150+
ℹ️ `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`]
151151

152152
ℹ️ The default value: `auto-safe`
153153

ipspot/ipv4.py

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

381381

382+
def _freeipapi_com_ipv4(geo: bool=False, timeout: Union[float, Tuple[float, float]]=5
383+
) -> Dict[str, Union[bool, Dict[str, Union[str, float]], str]]:
384+
"""
385+
Get public IP and geolocation using freeipapi.com.
386+
387+
:param geo: geolocation flag
388+
:param timeout: timeout value for API
389+
"""
390+
try:
391+
data = _get_json_ipv4_forced(url="https://freeipapi.com/api/json", timeout=timeout)
392+
result = {"status": True, "data": {"ip": data["ipAddress"], "api": "freeipapi.com"}}
393+
if geo:
394+
geo_data = {
395+
"city": data.get("cityName"),
396+
"region": data.get("regionName"),
397+
"country": data.get("countryName"),
398+
"country_code": data.get("countryCode"),
399+
"latitude": data.get("latitude"),
400+
"longitude": data.get("longitude"),
401+
"organization": None,
402+
"timezone": data.get("timeZone")
403+
}
404+
result["data"].update(geo_data)
405+
return result
406+
except Exception as e:
407+
return {"status": False, "error": str(e)}
408+
409+
382410
IPV4_API_MAP = {
383411
IPv4API.IFCONFIG_CO: {
384412
"thread_safe": False,
@@ -430,6 +458,11 @@ def _tnedi_me_ipv4(geo: bool=False, timeout: Union[float, Tuple[float, float]]
430458
"geo": True,
431459
"function": _reallyfreegeoip_org_ipv4
432460
},
461+
IPv4API.FREEIPAPI_COM: {
462+
"thread_safe": False,
463+
"geo": True,
464+
"function": _freeipapi_com_ipv4,
465+
}
433466
}
434467

435468

ipspot/params.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class IPv4API(Enum):
3333
MY_IP_IO = "my-ip.io"
3434
IFCONFIG_CO = "ifconfig.co"
3535
REALLYFREEGEOIP_ORG = "reallyfreegeoip.org"
36+
FREEIPAPI_COM = "freeipapi.com"
3637

3738

3839
PARAMETERS_NAME_MAP = {

tests/test_ipv4.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,26 @@ def test_public_ipv4_ifconfig_co_net_error():
193193
assert result["error"] == "No Internet"
194194

195195

196+
def test_public_ipv4_freeipapi_com_success():
197+
result = get_public_ipv4(api=IPv4API.FREEIPAPI_COM, geo=True)
198+
assert result["status"]
199+
assert is_ipv4(result["data"]["ip"])
200+
assert set(result["data"].keys()) == DATA_ITEMS
201+
assert result["data"]["api"] == "freeipapi.com"
202+
203+
204+
def test_public_ipv4_freeipapi_com_timeout_error():
205+
result = get_public_ipv4(api=IPv4API.FREEIPAPI_COM, geo=True, timeout="5")
206+
assert not result["status"]
207+
208+
209+
def test_public_ipv4_freeipapi_com_net_error():
210+
with mock.patch.object(requests.Session, "get", side_effect=Exception("No Internet")):
211+
result = get_public_ipv4(api=IPv4API.FREEIPAPI_COM)
212+
assert not result["status"]
213+
assert result["error"] == "No Internet"
214+
215+
196216
def test_public_ipv4_ip_api_com_success():
197217
result = get_public_ipv4(api=IPv4API.IP_API_COM, geo=True)
198218
assert result["status"]

0 commit comments

Comments
 (0)