ipspot 0.1__py3-none-any.whl → 0.2__py3-none-any.whl

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.
ipspot/functions.py CHANGED
@@ -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)
ipspot/params.py CHANGED
@@ -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
 
@@ -0,0 +1,11 @@
1
+ ipspot/__init__.py,sha256=cxty-JGyo_sLeQd7bHrXUoEabl3QhLtgA9UtLcStp6o,176
2
+ ipspot/__main__.py,sha256=17x2Q5vGORstO8mZ8B9aDixcOK5Gl71Ej5fC5P1EBKY,111
3
+ ipspot/functions.py,sha256=JNeLJw-zIZzQQhul1SHPBzBNiFtoJvjzMUIqkeJNn3A,7862
4
+ ipspot/params.py,sha256=I-waqgQ83px4ybrgpD1MAYFi7Zre1T9GSBN25-eZrVk,1099
5
+ ipspot-0.2.dist-info/licenses/AUTHORS.md,sha256=AgFL2paPd70ItL_YK18lWm_NjNWytKZHmR57o-et8kU,236
6
+ ipspot-0.2.dist-info/licenses/LICENSE,sha256=0aOd4wzZRoSH_35UZXRHS7alPFTtuFEBJrajLuonEIw,1067
7
+ ipspot-0.2.dist-info/METADATA,sha256=yQNY-arJj8IQfVT2vvySrEcytBVzvYCiac5QhLFK1Dk,8798
8
+ ipspot-0.2.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
9
+ ipspot-0.2.dist-info/entry_points.txt,sha256=SYgm9eGlJY7AGqi4_PmFVXwjEoylPPnAHeAeJPtYdjk,49
10
+ ipspot-0.2.dist-info/top_level.txt,sha256=v0WgE1z2iCy_bXU53fVcllwHLTvGNBIvq8u3KPC2_Sc,7
11
+ ipspot-0.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (79.0.1)
2
+ Generator: setuptools (80.3.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,11 +0,0 @@
1
- ipspot/__init__.py,sha256=cxty-JGyo_sLeQd7bHrXUoEabl3QhLtgA9UtLcStp6o,176
2
- ipspot/__main__.py,sha256=17x2Q5vGORstO8mZ8B9aDixcOK5Gl71Ej5fC5P1EBKY,111
3
- ipspot/functions.py,sha256=rXSoVRGDCDeH4anda8_o3rgE0jl5VqvfoDA-DL_bnDo,5936
4
- ipspot/params.py,sha256=J-O4-qaRLQCAVc9a0yKJpFC0LCOG1SvsHBgjA-T59pY,936
5
- ipspot-0.1.dist-info/licenses/AUTHORS.md,sha256=AgFL2paPd70ItL_YK18lWm_NjNWytKZHmR57o-et8kU,236
6
- ipspot-0.1.dist-info/licenses/LICENSE,sha256=0aOd4wzZRoSH_35UZXRHS7alPFTtuFEBJrajLuonEIw,1067
7
- ipspot-0.1.dist-info/METADATA,sha256=qtGhxEFLspKwu1qFF3IOE157RImRrlOroU2fbBdz7zs,7667
8
- ipspot-0.1.dist-info/WHEEL,sha256=SmOxYU7pzNKBqASvQJ7DjX3XGUF92lrGhMb3R6_iiqI,91
9
- ipspot-0.1.dist-info/entry_points.txt,sha256=SYgm9eGlJY7AGqi4_PmFVXwjEoylPPnAHeAeJPtYdjk,49
10
- ipspot-0.1.dist-info/top_level.txt,sha256=v0WgE1z2iCy_bXU53fVcllwHLTvGNBIvq8u3KPC2_Sc,7
11
- ipspot-0.1.dist-info/RECORD,,