ipspot 0.1__tar.gz → 0.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,6 +5,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
5
5
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
6
 
7
7
  ## [Unreleased]
8
+ ## [0.2] - 2025-05-04
9
+ ### Added
10
+ - Support [ip.sb](https://api.ip.sb/geoip)
11
+ - `--timeout` argument
12
+ ### Changed
13
+ - `README.md` updated
14
+ - Requests header updated
15
+ - Test system modified
8
16
  ## [0.1] - 2025-04-25
9
17
  ### Added
10
18
  - Support [ipinfo.io](https://ipinfo.io)
@@ -16,7 +24,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
16
24
  - `--no-geo` argument
17
25
  - Logo
18
26
 
19
- [Unreleased]: https://github.com/openscilab/ipspot/compare/v0.1...dev
27
+ [Unreleased]: https://github.com/openscilab/ipspot/compare/v0.2...dev
28
+ [0.2]: https://github.com/openscilab/ipspot/compare/v0.1...v0.2
20
29
  [0.1]: https://github.com/openscilab/ipspot/compare/3216fb7...v0.1
21
30
 
22
31
 
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ipspot
3
- Version: 0.1
3
+ Version: 0.2
4
4
  Summary: IPSpot: A Python Tool to Fetch the System's IP Address
5
5
  Home-page: https://github.com/openscilab/ipspot
6
- Download-URL: https://github.com/openscilab/ipspot/tarball/v0.1
6
+ Download-URL: https://github.com/openscilab/ipspot/tarball/v0.2
7
7
  Author: IPSpot Development Team
8
8
  Author-email: ipspot@openscilab.com
9
9
  License: MIT
@@ -55,6 +55,7 @@ Dynamic: summary
55
55
  <a href="https://badge.fury.io/py/ipspot"><img src="https://badge.fury.io/py/ipspot.svg" alt="PyPI version"></a>
56
56
  <a href="https://www.python.org/"><img src="https://img.shields.io/badge/built%20with-Python3-green.svg" alt="built with Python3"></a>
57
57
  <a href="https://github.com/openscilab/ipspot"><img alt="GitHub repo size" src="https://img.shields.io/github/repo-size/openscilab/ipspot"></a>
58
+ <a href="https://discord.gg/yyDV3T4cwU"><img src="https://img.shields.io/discord/1064533716615049236.svg" alt="Discord Channel"></a>
58
59
  </div>
59
60
 
60
61
  ## Overview
@@ -89,17 +90,25 @@ Dynamic: summary
89
90
  </tr>
90
91
  </table>
91
92
 
93
+ <table>
94
+ <tr>
95
+ <td align="center">Code Quality</td>
96
+ <td align="center"><a href="https://app.codacy.com/gh/openscilab/ipspot/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade"><img src="https://app.codacy.com/project/badge/Grade/cb2ab6584eb443b8a33da4d4252480bc"/></a></td>
97
+ <td align="center"><a href="https://www.codefactor.io/repository/github/openscilab/ipspot"><img src="https://www.codefactor.io/repository/github/openscilab/ipspot/badge" alt="CodeFactor"></a></td>
98
+ </tr>
99
+ </table>
100
+
92
101
 
93
102
  ## Installation
94
103
 
95
104
  ### Source Code
96
- - Download [Version 0.1](https://github.com/openscilab/ipspot/archive/v0.1.zip) or [Latest Source](https://github.com/openscilab/ipspot/archive/dev.zip)
105
+ - Download [Version 0.2](https://github.com/openscilab/ipspot/archive/v0.2.zip) or [Latest Source](https://github.com/openscilab/ipspot/archive/dev.zip)
97
106
  - `pip install .`
98
107
 
99
108
  ### PyPI
100
109
 
101
110
  - Check [Python Packaging User Guide](https://packaging.python.org/installing/)
102
- - `pip install ipspot==0.1`
111
+ - `pip install ipspot==0.2`
103
112
 
104
113
 
105
114
  ## Usage
@@ -112,7 +121,7 @@ Dynamic: summary
112
121
  >>> from ipspot import get_public_ipv4, IPv4API
113
122
  >>> get_public_ipv4(api=IPv4API.IPAPI)
114
123
  {'status': True, 'data': {'ip': 'xx.xx.xx.xx', 'api': 'ip-api.com'}}
115
- >>> get_public_ipv4(api=IPv4API.IPAPI, geo=True)
124
+ >>> get_public_ipv4(api=IPv4API.IPAPI, geo=True, timeout=10)
116
125
  {'data': {'country_code': 'GB', 'latitude': 50.9097, 'longitude': -1.4043, 'api': 'ip-api.com', 'country': 'United Kingdom', 'timezone': 'Europe/London', 'organization': '', 'region': 'England', 'ip': 'xx.xx.xx.xx', 'city': 'Southampton'}, 'status': True}
117
126
  ```
118
127
 
@@ -133,7 +142,7 @@ Dynamic: summary
133
142
  ```console
134
143
  > ipspot --version
135
144
 
136
- 0.1
145
+ 0.2
137
146
  ```
138
147
 
139
148
  #### Info
@@ -148,11 +157,11 @@ Dynamic: summary
148
157
  |___||_| |____/ | .__/ \___/ \__|
149
158
  |_|
150
159
 
151
- __ __ ___ _
152
- \ \ / / _ / _ \ / |
153
- \ \ / / (_)| | | | | |
154
- \ V / _ | |_| | _ | |
155
- \_/ (_) \___/ (_)|_|
160
+ __ __ ___ ____
161
+ \ \ / / _ / _ \ |___ \
162
+ \ \ / / (_)| | | | __) |
163
+ \ V / _ | |_| | _ / __/
164
+ \_/ (_) \___/ (_)|_____|
156
165
 
157
166
 
158
167
 
@@ -188,7 +197,7 @@ Public IP and Location Info:
188
197
 
189
198
  #### IPv4 API
190
199
 
191
- ℹ️ `ipv4-api` valid choices: [`auto`, `ipapi`, `ipinfo`]
200
+ ℹ️ `ipv4-api` valid choices: [`auto`, `ipapi`, `ipinfo`, `ipsb`]
192
201
 
193
202
  ℹ️ The default value: `auto`
194
203
 
@@ -231,7 +240,12 @@ Public IP:
231
240
  Just fill an issue and describe it. We'll check it ASAP!
232
241
 
233
242
  - Please complete the issue template
234
-
243
+
244
+ You can also join our discord server
245
+
246
+ <a href="https://discord.gg/yyDV3T4cwU">
247
+ <img src="https://img.shields.io/discord/1064533716615049236.svg?style=for-the-badge" alt="Discord Channel">
248
+ </a>
235
249
 
236
250
  ## Show Your Support
237
251
 
@@ -253,6 +267,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
253
267
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
254
268
 
255
269
  ## [Unreleased]
270
+ ## [0.2] - 2025-05-04
271
+ ### Added
272
+ - Support [ip.sb](https://api.ip.sb/geoip)
273
+ - `--timeout` argument
274
+ ### Changed
275
+ - `README.md` updated
276
+ - Requests header updated
277
+ - Test system modified
256
278
  ## [0.1] - 2025-04-25
257
279
  ### Added
258
280
  - Support [ipinfo.io](https://ipinfo.io)
@@ -264,7 +286,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
264
286
  - `--no-geo` argument
265
287
  - Logo
266
288
 
267
- [Unreleased]: https://github.com/openscilab/ipspot/compare/v0.1...dev
289
+ [Unreleased]: https://github.com/openscilab/ipspot/compare/v0.2...dev
290
+ [0.2]: https://github.com/openscilab/ipspot/compare/v0.1...v0.2
268
291
  [0.1]: https://github.com/openscilab/ipspot/compare/3216fb7...v0.1
269
292
 
270
293
 
@@ -5,6 +5,7 @@
5
5
  <a href="https://badge.fury.io/py/ipspot"><img src="https://badge.fury.io/py/ipspot.svg" alt="PyPI version"></a>
6
6
  <a href="https://www.python.org/"><img src="https://img.shields.io/badge/built%20with-Python3-green.svg" alt="built with Python3"></a>
7
7
  <a href="https://github.com/openscilab/ipspot"><img alt="GitHub repo size" src="https://img.shields.io/github/repo-size/openscilab/ipspot"></a>
8
+ <a href="https://discord.gg/yyDV3T4cwU"><img src="https://img.shields.io/discord/1064533716615049236.svg" alt="Discord Channel"></a>
8
9
  </div>
9
10
 
10
11
  ## Overview
@@ -39,17 +40,25 @@
39
40
  </tr>
40
41
  </table>
41
42
 
43
+ <table>
44
+ <tr>
45
+ <td align="center">Code Quality</td>
46
+ <td align="center"><a href="https://app.codacy.com/gh/openscilab/ipspot/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade"><img src="https://app.codacy.com/project/badge/Grade/cb2ab6584eb443b8a33da4d4252480bc"/></a></td>
47
+ <td align="center"><a href="https://www.codefactor.io/repository/github/openscilab/ipspot"><img src="https://www.codefactor.io/repository/github/openscilab/ipspot/badge" alt="CodeFactor"></a></td>
48
+ </tr>
49
+ </table>
50
+
42
51
 
43
52
  ## Installation
44
53
 
45
54
  ### Source Code
46
- - Download [Version 0.1](https://github.com/openscilab/ipspot/archive/v0.1.zip) or [Latest Source](https://github.com/openscilab/ipspot/archive/dev.zip)
55
+ - Download [Version 0.2](https://github.com/openscilab/ipspot/archive/v0.2.zip) or [Latest Source](https://github.com/openscilab/ipspot/archive/dev.zip)
47
56
  - `pip install .`
48
57
 
49
58
  ### PyPI
50
59
 
51
60
  - Check [Python Packaging User Guide](https://packaging.python.org/installing/)
52
- - `pip install ipspot==0.1`
61
+ - `pip install ipspot==0.2`
53
62
 
54
63
 
55
64
  ## Usage
@@ -62,7 +71,7 @@
62
71
  >>> from ipspot import get_public_ipv4, IPv4API
63
72
  >>> get_public_ipv4(api=IPv4API.IPAPI)
64
73
  {'status': True, 'data': {'ip': 'xx.xx.xx.xx', 'api': 'ip-api.com'}}
65
- >>> get_public_ipv4(api=IPv4API.IPAPI, geo=True)
74
+ >>> get_public_ipv4(api=IPv4API.IPAPI, geo=True, timeout=10)
66
75
  {'data': {'country_code': 'GB', 'latitude': 50.9097, 'longitude': -1.4043, 'api': 'ip-api.com', 'country': 'United Kingdom', 'timezone': 'Europe/London', 'organization': '', 'region': 'England', 'ip': 'xx.xx.xx.xx', 'city': 'Southampton'}, 'status': True}
67
76
  ```
68
77
 
@@ -83,7 +92,7 @@
83
92
  ```console
84
93
  > ipspot --version
85
94
 
86
- 0.1
95
+ 0.2
87
96
  ```
88
97
 
89
98
  #### Info
@@ -98,11 +107,11 @@
98
107
  |___||_| |____/ | .__/ \___/ \__|
99
108
  |_|
100
109
 
101
- __ __ ___ _
102
- \ \ / / _ / _ \ / |
103
- \ \ / / (_)| | | | | |
104
- \ V / _ | |_| | _ | |
105
- \_/ (_) \___/ (_)|_|
110
+ __ __ ___ ____
111
+ \ \ / / _ / _ \ |___ \
112
+ \ \ / / (_)| | | | __) |
113
+ \ V / _ | |_| | _ / __/
114
+ \_/ (_) \___/ (_)|_____|
106
115
 
107
116
 
108
117
 
@@ -138,7 +147,7 @@ Public IP and Location Info:
138
147
 
139
148
  #### IPv4 API
140
149
 
141
- ℹ️ `ipv4-api` valid choices: [`auto`, `ipapi`, `ipinfo`]
150
+ ℹ️ `ipv4-api` valid choices: [`auto`, `ipapi`, `ipinfo`, `ipsb`]
142
151
 
143
152
  ℹ️ The default value: `auto`
144
153
 
@@ -181,7 +190,12 @@ Public IP:
181
190
  Just fill an issue and describe it. We'll check it ASAP!
182
191
 
183
192
  - Please complete the issue template
184
-
193
+
194
+ You can also join our discord server
195
+
196
+ <a href="https://discord.gg/yyDV3T4cwU">
197
+ <img src="https://img.shields.io/discord/1064533716615049236.svg?style=for-the-badge" alt="Discord Channel">
198
+ </a>
185
199
 
186
200
  ## Show Your Support
187
201
 
@@ -4,8 +4,8 @@
4
4
 
5
5
  | Version | Supported |
6
6
  | ------------- | ------------------ |
7
- | 0.1 | :white_check_mark: |
8
- | < 0.1 | :x: |
7
+ | 0.2 | :white_check_mark: |
8
+ | < 0.2 | :x: |
9
9
 
10
10
  ## Reporting a Vulnerability
11
11
 
@@ -1,6 +1,8 @@
1
- requests==2.31.0
1
+ requests==2.32.3
2
2
  art==6.5
3
3
  setuptools>=40.8.0
4
4
  vulture>=1.0
5
5
  bandit>=1.5.1
6
6
  pydocstyle>=3.0.0
7
+ pytest>=4.3.1
8
+ pytest-cov>=2.6.1
@@ -2,19 +2,19 @@
2
2
  """ipspot functions."""
3
3
  import argparse
4
4
  import socket
5
- from typing import Union, Dict, Any
5
+ from typing import Union, Dict, Tuple, Any
6
6
  import requests
7
7
  from art import tprint
8
- from .params import IPv4API, PARAMETERS_NAME_MAP
8
+ from .params import REQUEST_HEADERS, IPv4API, PARAMETERS_NAME_MAP
9
9
  from .params import IPSPOT_OVERVIEW, IPSPOT_REPO, IPSPOT_VERSION
10
10
 
11
11
 
12
- def ipspot_info() -> None:
12
+ def ipspot_info() -> None: # pragma: no cover
13
13
  """Print ipspot details."""
14
14
  tprint("IPSpot")
15
15
  tprint("V:" + IPSPOT_VERSION)
16
16
  print(IPSPOT_OVERVIEW)
17
- print(IPSPOT_REPO)
17
+ print("Repo : " + IPSPOT_REPO)
18
18
 
19
19
 
20
20
  def get_private_ipv4() -> Dict[str, Union[bool, Dict[str, str], str]]:
@@ -27,14 +27,46 @@ def get_private_ipv4() -> Dict[str, Union[bool, Dict[str, str], str]]:
27
27
  return {"status": False, "error": str(e)}
28
28
 
29
29
 
30
- def _ipapi_ipv4(geo: bool=False) -> Dict[str, Union[bool, Dict[str, Union[str, float]], str]]:
30
+ def _ipsb_ipv4(geo: bool=False, timeout: Union[float, Tuple[float, float]]
31
+ =5) -> Dict[str, Union[bool, Dict[str, Union[str, float]], str]]:
32
+ """
33
+ Get public IP and geolocation using ip.sb.
34
+
35
+ :param geo: geolocation flag
36
+ :param timeout: timeout value for API
37
+ """
38
+ try:
39
+ response = requests.get("https://api.ip.sb/geoip", headers=REQUEST_HEADERS, timeout=timeout)
40
+ response.raise_for_status()
41
+ data = response.json()
42
+ result = {"status": True, "data": {"ip": data.get("ip"), "api": "ip.sb"}}
43
+ if geo:
44
+ geo_data = {
45
+ "city": data.get("city"),
46
+ "region": data.get("region"),
47
+ "country": data.get("country"),
48
+ "country_code": data.get("country_code"),
49
+ "latitude": data.get("latitude"),
50
+ "longitude": data.get("longitude"),
51
+ "organization": data.get("organization"),
52
+ "timezone": data.get("timezone")
53
+ }
54
+ result["data"].update(geo_data)
55
+ return result
56
+ except Exception as e:
57
+ return {"status": False, "error": str(e)}
58
+
59
+
60
+ def _ipapi_ipv4(geo: bool=False, timeout: Union[float, Tuple[float, float]]
61
+ =5) -> Dict[str, Union[bool, Dict[str, Union[str, float]], str]]:
31
62
  """
32
63
  Get public IP and geolocation using ip-api.com.
33
64
 
34
65
  :param geo: geolocation flag
66
+ :param timeout: timeout value for API
35
67
  """
36
68
  try:
37
- response = requests.get("http://ip-api.com/json/", timeout=5)
69
+ response = requests.get("http://ip-api.com/json/", headers=REQUEST_HEADERS, timeout=timeout)
38
70
  response.raise_for_status()
39
71
  data = response.json()
40
72
 
@@ -58,14 +90,16 @@ def _ipapi_ipv4(geo: bool=False) -> Dict[str, Union[bool, Dict[str, Union[str, f
58
90
  return {"status": False, "error": str(e)}
59
91
 
60
92
 
61
- def _ipinfo_ipv4(geo: bool=False) -> Dict[str, Union[bool, Dict[str, Union[str, float]], str]]:
93
+ def _ipinfo_ipv4(geo: bool=False, timeout: Union[float, Tuple[float, float]]
94
+ =5) -> Dict[str, Union[bool, Dict[str, Union[str, float]], str]]:
62
95
  """
63
96
  Get public IP and geolocation using ipinfo.io.
64
97
 
65
98
  :param geo: geolocation flag
99
+ :param timeout: timeout value for API
66
100
  """
67
101
  try:
68
- response = requests.get("https://ipinfo.io/json", timeout=5)
102
+ response = requests.get("https://ipinfo.io/json", headers=REQUEST_HEADERS, timeout=timeout)
69
103
  response.raise_for_status()
70
104
  data = response.json()
71
105
  result = {"status": True, "data": {"ip": data.get("ip"), "api": "ipinfo.io"}}
@@ -87,29 +121,31 @@ def _ipinfo_ipv4(geo: bool=False) -> Dict[str, Union[bool, Dict[str, Union[str,
87
121
  return {"status": False, "error": str(e)}
88
122
 
89
123
 
90
- def get_public_ipv4(api: IPv4API=IPv4API.AUTO,
91
- geo: bool=False) -> Dict[str, Union[bool, Dict[str, Union[str, float]], str]]:
124
+ def get_public_ipv4(api: IPv4API=IPv4API.AUTO, geo: bool=False,
125
+ timeout: Union[float, Tuple[float, float]]=5) -> Dict[str, Union[bool, Dict[str, Union[str, float]], str]]:
92
126
  """
93
127
  Get public IPv4 and geolocation info based on the selected API.
94
128
 
95
129
  :param api: public IPv4 API
96
130
  :param geo: geolocation flag
131
+ :param timeout: timeout value for API
97
132
  """
98
133
  api_map = {
99
134
  IPv4API.IPAPI: _ipapi_ipv4,
100
135
  IPv4API.IPINFO: _ipinfo_ipv4,
136
+ IPv4API.IPSB: _ipsb_ipv4
101
137
  }
102
138
 
103
139
  if api == IPv4API.AUTO:
104
140
  for _, func in api_map.items():
105
- result = func(geo=geo)
141
+ result = func(geo=geo, timeout=timeout)
106
142
  if result["status"]:
107
143
  return result
108
144
  return {"status": False, "error": "All attempts failed."}
109
145
  else:
110
146
  func = api_map.get(api)
111
147
  if func:
112
- return func(geo=geo)
148
+ return func(geo=geo, timeout=timeout)
113
149
  return {"status": False, "error": "Unsupported API: {api}".format(api=api)}
114
150
 
115
151
 
@@ -126,12 +162,14 @@ def filter_parameter(parameter: Any) -> Any:
126
162
  return parameter
127
163
 
128
164
 
129
- def display_ip_info(ipv4_api: IPv4API = IPv4API.AUTO, geo: bool=False) -> None:
165
+ def display_ip_info(ipv4_api: IPv4API = IPv4API.AUTO, geo: bool=False,
166
+ timeout: Union[float, Tuple[float, float]]=5) -> None: # pragma: no cover
130
167
  """
131
168
  Print collected IP and location data.
132
169
 
133
170
  :param ipv4_api: public IPv4 API
134
171
  :param geo: geolocation flag
172
+ :param timeout: timeout value for API
135
173
  """
136
174
  private_result = get_private_ipv4()
137
175
  print("Private IP:\n")
@@ -143,7 +181,7 @@ def display_ip_info(ipv4_api: IPv4API = IPv4API.AUTO, geo: bool=False) -> None:
143
181
  public_title += " and Location Info"
144
182
  public_title += ":\n"
145
183
  print(public_title)
146
- public_result = get_public_ipv4(ipv4_api, geo=geo)
184
+ public_result = get_public_ipv4(ipv4_api, geo=geo, timeout=timeout)
147
185
  if public_result["status"]:
148
186
  for name, parameter in sorted(public_result["data"].items()):
149
187
  print(
@@ -154,7 +192,7 @@ def display_ip_info(ipv4_api: IPv4API = IPv4API.AUTO, geo: bool=False) -> None:
154
192
  print(" Error: {public_result[error]}".format(public_result=public_result))
155
193
 
156
194
 
157
- def main() -> None:
195
+ def main() -> None: # pragma: no cover
158
196
  """CLI main function."""
159
197
  parser = argparse.ArgumentParser()
160
198
  parser.add_argument(
@@ -167,6 +205,7 @@ def main() -> None:
167
205
  parser.add_argument('--info', help='info', nargs="?", const=1)
168
206
  parser.add_argument('--version', help='version', nargs="?", const=1)
169
207
  parser.add_argument('--no-geo', help='no geolocation data', nargs="?", const=1, default=False)
208
+ parser.add_argument('--timeout', help='timeout for the API request', type=float, default=5.0)
170
209
 
171
210
  args = parser.parse_args()
172
211
  if args.version:
@@ -176,4 +215,4 @@ def main() -> None:
176
215
  else:
177
216
  ipv4_api = IPv4API(args.ipv4_api)
178
217
  geo = not args.no_geo
179
- display_ip_info(ipv4_api=ipv4_api, geo=geo)
218
+ display_ip_info(ipv4_api=ipv4_api, geo=geo, timeout=args.timeout)
@@ -2,7 +2,7 @@
2
2
  """ipspot params."""
3
3
  from enum import Enum
4
4
 
5
- IPSPOT_VERSION = "0.1"
5
+ IPSPOT_VERSION = "0.2"
6
6
 
7
7
  IPSPOT_OVERVIEW = '''
8
8
  IPSpot is a Python library for retrieving the current system's IP address and location information.
@@ -10,7 +10,12 @@ It currently supports public and private IPv4 detection using multiple API provi
10
10
  Designed with simplicity and modularity in mind, IPSpot offers quick IP and geolocation lookups directly from your machine.
11
11
  '''
12
12
 
13
- IPSPOT_REPO = "Repo : https://github.com/openscilab/ipspot"
13
+ IPSPOT_REPO = "https://github.com/openscilab/ipspot"
14
+
15
+ REQUEST_HEADERS = {
16
+ 'User-Agent': 'IPSpot/{version} ({repo})'.format(version=IPSPOT_VERSION, repo=IPSPOT_REPO),
17
+ 'Accept': 'application/json'
18
+ }
14
19
 
15
20
 
16
21
  class IPv4API(Enum):
@@ -19,6 +24,7 @@ class IPv4API(Enum):
19
24
  AUTO = "auto"
20
25
  IPAPI = "ipapi"
21
26
  IPINFO = "ipinfo"
27
+ IPSB = "ipsb"
22
28
 
23
29
 
24
30
  PARAMETERS_NAME_MAP = {
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ipspot
3
- Version: 0.1
3
+ Version: 0.2
4
4
  Summary: IPSpot: A Python Tool to Fetch the System's IP Address
5
5
  Home-page: https://github.com/openscilab/ipspot
6
- Download-URL: https://github.com/openscilab/ipspot/tarball/v0.1
6
+ Download-URL: https://github.com/openscilab/ipspot/tarball/v0.2
7
7
  Author: IPSpot Development Team
8
8
  Author-email: ipspot@openscilab.com
9
9
  License: MIT
@@ -55,6 +55,7 @@ Dynamic: summary
55
55
  <a href="https://badge.fury.io/py/ipspot"><img src="https://badge.fury.io/py/ipspot.svg" alt="PyPI version"></a>
56
56
  <a href="https://www.python.org/"><img src="https://img.shields.io/badge/built%20with-Python3-green.svg" alt="built with Python3"></a>
57
57
  <a href="https://github.com/openscilab/ipspot"><img alt="GitHub repo size" src="https://img.shields.io/github/repo-size/openscilab/ipspot"></a>
58
+ <a href="https://discord.gg/yyDV3T4cwU"><img src="https://img.shields.io/discord/1064533716615049236.svg" alt="Discord Channel"></a>
58
59
  </div>
59
60
 
60
61
  ## Overview
@@ -89,17 +90,25 @@ Dynamic: summary
89
90
  </tr>
90
91
  </table>
91
92
 
93
+ <table>
94
+ <tr>
95
+ <td align="center">Code Quality</td>
96
+ <td align="center"><a href="https://app.codacy.com/gh/openscilab/ipspot/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade"><img src="https://app.codacy.com/project/badge/Grade/cb2ab6584eb443b8a33da4d4252480bc"/></a></td>
97
+ <td align="center"><a href="https://www.codefactor.io/repository/github/openscilab/ipspot"><img src="https://www.codefactor.io/repository/github/openscilab/ipspot/badge" alt="CodeFactor"></a></td>
98
+ </tr>
99
+ </table>
100
+
92
101
 
93
102
  ## Installation
94
103
 
95
104
  ### Source Code
96
- - Download [Version 0.1](https://github.com/openscilab/ipspot/archive/v0.1.zip) or [Latest Source](https://github.com/openscilab/ipspot/archive/dev.zip)
105
+ - Download [Version 0.2](https://github.com/openscilab/ipspot/archive/v0.2.zip) or [Latest Source](https://github.com/openscilab/ipspot/archive/dev.zip)
97
106
  - `pip install .`
98
107
 
99
108
  ### PyPI
100
109
 
101
110
  - Check [Python Packaging User Guide](https://packaging.python.org/installing/)
102
- - `pip install ipspot==0.1`
111
+ - `pip install ipspot==0.2`
103
112
 
104
113
 
105
114
  ## Usage
@@ -112,7 +121,7 @@ Dynamic: summary
112
121
  >>> from ipspot import get_public_ipv4, IPv4API
113
122
  >>> get_public_ipv4(api=IPv4API.IPAPI)
114
123
  {'status': True, 'data': {'ip': 'xx.xx.xx.xx', 'api': 'ip-api.com'}}
115
- >>> get_public_ipv4(api=IPv4API.IPAPI, geo=True)
124
+ >>> get_public_ipv4(api=IPv4API.IPAPI, geo=True, timeout=10)
116
125
  {'data': {'country_code': 'GB', 'latitude': 50.9097, 'longitude': -1.4043, 'api': 'ip-api.com', 'country': 'United Kingdom', 'timezone': 'Europe/London', 'organization': '', 'region': 'England', 'ip': 'xx.xx.xx.xx', 'city': 'Southampton'}, 'status': True}
117
126
  ```
118
127
 
@@ -133,7 +142,7 @@ Dynamic: summary
133
142
  ```console
134
143
  > ipspot --version
135
144
 
136
- 0.1
145
+ 0.2
137
146
  ```
138
147
 
139
148
  #### Info
@@ -148,11 +157,11 @@ Dynamic: summary
148
157
  |___||_| |____/ | .__/ \___/ \__|
149
158
  |_|
150
159
 
151
- __ __ ___ _
152
- \ \ / / _ / _ \ / |
153
- \ \ / / (_)| | | | | |
154
- \ V / _ | |_| | _ | |
155
- \_/ (_) \___/ (_)|_|
160
+ __ __ ___ ____
161
+ \ \ / / _ / _ \ |___ \
162
+ \ \ / / (_)| | | | __) |
163
+ \ V / _ | |_| | _ / __/
164
+ \_/ (_) \___/ (_)|_____|
156
165
 
157
166
 
158
167
 
@@ -188,7 +197,7 @@ Public IP and Location Info:
188
197
 
189
198
  #### IPv4 API
190
199
 
191
- ℹ️ `ipv4-api` valid choices: [`auto`, `ipapi`, `ipinfo`]
200
+ ℹ️ `ipv4-api` valid choices: [`auto`, `ipapi`, `ipinfo`, `ipsb`]
192
201
 
193
202
  ℹ️ The default value: `auto`
194
203
 
@@ -231,7 +240,12 @@ Public IP:
231
240
  Just fill an issue and describe it. We'll check it ASAP!
232
241
 
233
242
  - Please complete the issue template
234
-
243
+
244
+ You can also join our discord server
245
+
246
+ <a href="https://discord.gg/yyDV3T4cwU">
247
+ <img src="https://img.shields.io/discord/1064533716615049236.svg?style=for-the-badge" alt="Discord Channel">
248
+ </a>
235
249
 
236
250
  ## Show Your Support
237
251
 
@@ -253,6 +267,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
253
267
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
254
268
 
255
269
  ## [Unreleased]
270
+ ## [0.2] - 2025-05-04
271
+ ### Added
272
+ - Support [ip.sb](https://api.ip.sb/geoip)
273
+ - `--timeout` argument
274
+ ### Changed
275
+ - `README.md` updated
276
+ - Requests header updated
277
+ - Test system modified
256
278
  ## [0.1] - 2025-04-25
257
279
  ### Added
258
280
  - Support [ipinfo.io](https://ipinfo.io)
@@ -264,7 +286,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
264
286
  - `--no-geo` argument
265
287
  - Logo
266
288
 
267
- [Unreleased]: https://github.com/openscilab/ipspot/compare/v0.1...dev
289
+ [Unreleased]: https://github.com/openscilab/ipspot/compare/v0.2...dev
290
+ [0.2]: https://github.com/openscilab/ipspot/compare/v0.1...v0.2
268
291
  [0.1]: https://github.com/openscilab/ipspot/compare/3216fb7...v0.1
269
292
 
270
293
 
@@ -16,4 +16,6 @@ ipspot.egg-info/SOURCES.txt
16
16
  ipspot.egg-info/dependency_links.txt
17
17
  ipspot.egg-info/entry_points.txt
18
18
  ipspot.egg-info/requires.txt
19
- ipspot.egg-info/top_level.txt
19
+ ipspot.egg-info/top_level.txt
20
+ tests/test_functions.py
21
+ tests/test_ipv4.py
@@ -32,7 +32,7 @@ def read_description() -> str:
32
32
  setup(
33
33
  name='ipspot',
34
34
  packages=['ipspot'],
35
- version='0.1',
35
+ version='0.2',
36
36
  description='IPSpot: A Python Tool to Fetch the System\'s IP Address',
37
37
  long_description=read_description(),
38
38
  long_description_content_type='text/markdown',
@@ -40,7 +40,7 @@ setup(
40
40
  author='IPSpot Development Team',
41
41
  author_email='ipspot@openscilab.com',
42
42
  url='https://github.com/openscilab/ipspot',
43
- download_url='https://github.com/openscilab/ipspot/tarball/v0.1',
43
+ download_url='https://github.com/openscilab/ipspot/tarball/v0.2',
44
44
  keywords="ip ipv4 geo geolocation network location ipspot cli",
45
45
  project_urls={
46
46
  'Source': 'https://github.com/openscilab/ipspot'
@@ -0,0 +1,24 @@
1
+ from ipspot.functions import filter_parameter
2
+
3
+ TEST_CASE_NAME = "Functions tests"
4
+
5
+
6
+ def test_filter_parameter1():
7
+ assert filter_parameter(None) == "N/A"
8
+
9
+
10
+ def test_filter_parameter2():
11
+ assert filter_parameter("") == "N/A"
12
+
13
+
14
+ def test_filter_parameter3():
15
+ assert filter_parameter(" ") == "N/A"
16
+
17
+
18
+ def test_filter_parameter4():
19
+ assert filter_parameter("GB") == "GB"
20
+
21
+
22
+
23
+
24
+
@@ -0,0 +1,108 @@
1
+ import re
2
+ from unittest import mock
3
+ from ipspot import get_private_ipv4
4
+ from ipspot import get_public_ipv4, IPv4API
5
+
6
+ TEST_CASE_NAME = "IPv4 tests"
7
+ IPV4_REGEX = re.compile(r'^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$')
8
+ DATA_ITEMS = {'country_code', 'latitude', 'longitude', 'api', 'country', 'timezone', 'organization', 'region', 'ip', 'city'}
9
+
10
+
11
+ def test_private_ipv4_success():
12
+ result = get_private_ipv4()
13
+ assert result["status"]
14
+ assert IPV4_REGEX.match(result["data"]["ip"])
15
+
16
+
17
+ def test_private_ipv4_error():
18
+ with mock.patch("socket.gethostbyname", side_effect=Exception("Test error")):
19
+ result = get_private_ipv4()
20
+ assert not result["status"]
21
+ assert result["error"] == "Test error"
22
+
23
+
24
+ def test_public_ipv4_auto_success():
25
+ result = get_public_ipv4(api=IPv4API.AUTO, geo=True)
26
+ assert result["status"]
27
+ assert IPV4_REGEX.match(result["data"]["ip"])
28
+ assert set(result["data"].keys()) == DATA_ITEMS
29
+
30
+
31
+ def test_public_ipv4_auto_timeout_error():
32
+ result = get_public_ipv4(api=IPv4API.AUTO, geo=True, timeout="5")
33
+ assert not result["status"]
34
+
35
+
36
+ def test_public_ipv4_auto_net_error():
37
+ with mock.patch("requests.get", side_effect=Exception("No Internet")):
38
+ result = get_public_ipv4(api=IPv4API.AUTO)
39
+ assert not result["status"]
40
+ assert result["error"] == "All attempts failed."
41
+
42
+
43
+ def test_public_ipv4_ipapi_success():
44
+ result = get_public_ipv4(api=IPv4API.IPAPI, geo=True)
45
+ assert result["status"]
46
+ assert IPV4_REGEX.match(result["data"]["ip"])
47
+ assert set(result["data"].keys()) == DATA_ITEMS
48
+ assert result["data"]["api"] == "ip-api.com"
49
+
50
+
51
+ def test_public_ipv4_ipapi_timeout_error():
52
+ result = get_public_ipv4(api=IPv4API.IPAPI, geo=True, timeout="5")
53
+ assert not result["status"]
54
+
55
+
56
+ def test_public_ipv4_ipapi_net_error():
57
+ with mock.patch("requests.get", side_effect=Exception("No Internet")):
58
+ result = get_public_ipv4(api=IPv4API.IPAPI)
59
+ assert not result["status"]
60
+ assert result["error"] == "No Internet"
61
+
62
+
63
+ def test_public_ipv4_ipinfo_success():
64
+ result = get_public_ipv4(api=IPv4API.IPINFO, geo=True)
65
+ assert result["status"]
66
+ assert IPV4_REGEX.match(result["data"]["ip"])
67
+ assert set(result["data"].keys()) == DATA_ITEMS
68
+ assert result["data"]["api"] == "ipinfo.io"
69
+
70
+
71
+ def test_public_ipv4_ipinfo_timeout_error():
72
+ result = get_public_ipv4(api=IPv4API.IPINFO, geo=True, timeout="5")
73
+ assert not result["status"]
74
+
75
+
76
+ def test_public_ipv4_ipinfo_net_error():
77
+ with mock.patch("requests.get", side_effect=Exception("No Internet")):
78
+ result = get_public_ipv4(api=IPv4API.IPINFO)
79
+ assert not result["status"]
80
+ assert result["error"] == "No Internet"
81
+
82
+
83
+ def test_public_ipv4_ipsb_success():
84
+ result = get_public_ipv4(api=IPv4API.IPSB, geo=True)
85
+ assert result["status"]
86
+ assert IPV4_REGEX.match(result["data"]["ip"])
87
+ assert set(result["data"].keys()) == DATA_ITEMS
88
+ assert result["data"]["api"] == "ip.sb"
89
+
90
+
91
+ def test_public_ipv4_ipsb_timeout_error():
92
+ result = get_public_ipv4(api=IPv4API.IPSB, geo=True, timeout="5")
93
+ assert not result["status"]
94
+
95
+
96
+
97
+ def test_public_ipv4_ipsb_net_error():
98
+ with mock.patch("requests.get", side_effect=Exception("No Internet")):
99
+ result = get_public_ipv4(api=IPv4API.IPSB)
100
+ assert not result["status"]
101
+ assert result["error"] == "No Internet"
102
+
103
+
104
+ def test_public_ipv4_api_error():
105
+ result = get_public_ipv4(api="api1", geo=True)
106
+ assert not result["status"]
107
+ assert result["error"] == "Unsupported API: api1"
108
+
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes