netcheck-cli 0.1.0__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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Marcus
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,75 @@
1
+ Metadata-Version: 2.4
2
+ Name: netcheck-cli
3
+ Version: 0.1.0
4
+ Summary: Network diagnostics CLI — DNS, ping, HTTP check, SSL certs, latency
5
+ Author-email: Marcus <marcus.builds.things@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/marcusbuildsthings-droid/netcheck
8
+ Project-URL: Issues, https://github.com/marcusbuildsthings-droid/netcheck/issues
9
+ Keywords: network,dns,ping,ssl,diagnostics,cli
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Intended Audience :: System Administrators
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Topic :: System :: Networking
17
+ Classifier: Topic :: Utilities
18
+ Requires-Python: >=3.9
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: click>=8.0
22
+ Dynamic: license-file
23
+
24
+ # netcheck-cli
25
+
26
+ Network diagnostics from the command line — DNS lookup, ping, HTTP check, SSL cert info, latency, port scan, and IP lookup.
27
+
28
+ ## Install
29
+
30
+ ```bash
31
+ pip install netcheck-cli
32
+ ```
33
+
34
+ ## Usage
35
+
36
+ ```bash
37
+ # DNS lookup
38
+ netcheck dns example.com
39
+ netcheck dns example.com --type MX
40
+
41
+ # Ping
42
+ netcheck ping example.com -c 4
43
+
44
+ # HTTP endpoint check
45
+ netcheck http https://example.com
46
+ netcheck http api.example.com --method HEAD
47
+
48
+ # SSL certificate info
49
+ netcheck cert example.com
50
+ netcheck cert example.com --port 8443
51
+
52
+ # TCP latency measurement
53
+ netcheck latency example.com -n 10
54
+
55
+ # Port scan
56
+ netcheck scan example.com -p 80,443,8080
57
+
58
+ # Public + local IP
59
+ netcheck ip
60
+ ```
61
+
62
+ All commands support `--json` for machine-readable output:
63
+
64
+ ```bash
65
+ netcheck --json dns example.com
66
+ netcheck --json cert example.com
67
+ ```
68
+
69
+ ## For AI Agents
70
+
71
+ See [SKILL.md](SKILL.md) for agent-optimized documentation.
72
+
73
+ ## License
74
+
75
+ MIT
@@ -0,0 +1,52 @@
1
+ # netcheck-cli
2
+
3
+ Network diagnostics from the command line — DNS lookup, ping, HTTP check, SSL cert info, latency, port scan, and IP lookup.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pip install netcheck-cli
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```bash
14
+ # DNS lookup
15
+ netcheck dns example.com
16
+ netcheck dns example.com --type MX
17
+
18
+ # Ping
19
+ netcheck ping example.com -c 4
20
+
21
+ # HTTP endpoint check
22
+ netcheck http https://example.com
23
+ netcheck http api.example.com --method HEAD
24
+
25
+ # SSL certificate info
26
+ netcheck cert example.com
27
+ netcheck cert example.com --port 8443
28
+
29
+ # TCP latency measurement
30
+ netcheck latency example.com -n 10
31
+
32
+ # Port scan
33
+ netcheck scan example.com -p 80,443,8080
34
+
35
+ # Public + local IP
36
+ netcheck ip
37
+ ```
38
+
39
+ All commands support `--json` for machine-readable output:
40
+
41
+ ```bash
42
+ netcheck --json dns example.com
43
+ netcheck --json cert example.com
44
+ ```
45
+
46
+ ## For AI Agents
47
+
48
+ See [SKILL.md](SKILL.md) for agent-optimized documentation.
49
+
50
+ ## License
51
+
52
+ MIT
@@ -0,0 +1,2 @@
1
+ """netcheck-cli — Network diagnostics from the command line."""
2
+ __version__ = "0.1.0"
@@ -0,0 +1,391 @@
1
+ """netcheck-cli — Network diagnostics CLI."""
2
+ import click
3
+ import json as _json
4
+ import socket
5
+ import ssl
6
+ import subprocess
7
+ import sys
8
+ import time
9
+ import urllib.request
10
+ import urllib.error
11
+ from datetime import datetime, timezone
12
+
13
+
14
+ def _out(data, as_json):
15
+ if as_json:
16
+ click.echo(_json.dumps(data, indent=2, default=str))
17
+ else:
18
+ for k, v in data.items():
19
+ if isinstance(v, list):
20
+ click.echo(f" {k}:")
21
+ for item in v:
22
+ click.echo(f" - {item}")
23
+ elif isinstance(v, dict):
24
+ click.echo(f" {k}:")
25
+ for sk, sv in v.items():
26
+ click.echo(f" {sk}: {sv}")
27
+ else:
28
+ click.echo(f" {k}: {v}")
29
+
30
+
31
+ @click.group()
32
+ @click.option("--json", "as_json", is_flag=True, help="JSON output")
33
+ @click.pass_context
34
+ def cli(ctx, as_json):
35
+ """Network diagnostics CLI."""
36
+ ctx.ensure_object(dict)
37
+ ctx.obj["json"] = as_json
38
+
39
+
40
+ @cli.command()
41
+ @click.argument("hostname")
42
+ @click.option("--type", "record_type", default="A", help="Record type (A, AAAA, MX, etc.)")
43
+ @click.pass_context
44
+ def dns(ctx, hostname, record_type):
45
+ """DNS lookup for a hostname."""
46
+ as_json = ctx.obj["json"]
47
+ result = {"hostname": hostname, "type": record_type}
48
+ try:
49
+ if record_type.upper() in ("A", "AAAA"):
50
+ family = socket.AF_INET if record_type.upper() == "A" else socket.AF_INET6
51
+ try:
52
+ addrs = socket.getaddrinfo(hostname, None, family, socket.SOCK_STREAM)
53
+ ips = sorted(set(a[4][0] for a in addrs))
54
+ except socket.gaierror:
55
+ ips = []
56
+ result["addresses"] = ips
57
+ result["count"] = len(ips)
58
+ if not as_json:
59
+ click.echo(f"DNS {record_type} lookup: {hostname}")
60
+ if ips:
61
+ for ip in ips:
62
+ click.echo(f" {ip}")
63
+ else:
64
+ click.echo(" No records found")
65
+ return
66
+ else:
67
+ # Use dig/nslookup for other record types
68
+ try:
69
+ out = subprocess.run(
70
+ ["dig", "+short", hostname, record_type.upper()],
71
+ capture_output=True, text=True, timeout=10
72
+ )
73
+ records = [l.strip() for l in out.stdout.strip().split("\n") if l.strip()]
74
+ result["records"] = records
75
+ result["count"] = len(records)
76
+ if not as_json:
77
+ click.echo(f"DNS {record_type} lookup: {hostname}")
78
+ for r in records:
79
+ click.echo(f" {r}")
80
+ if not records:
81
+ click.echo(" No records found")
82
+ return
83
+ except FileNotFoundError:
84
+ result["error"] = "dig not found; install bind/dnsutils for non-A/AAAA lookups"
85
+ if not as_json:
86
+ click.echo(f"Error: {result['error']}", err=True)
87
+ sys.exit(1)
88
+ except Exception as e:
89
+ result["error"] = str(e)
90
+ if not as_json:
91
+ click.echo(f"Error: {e}", err=True)
92
+ sys.exit(1)
93
+ if as_json:
94
+ click.echo(_json.dumps(result, indent=2))
95
+
96
+
97
+ @cli.command()
98
+ @click.argument("host")
99
+ @click.option("-c", "--count", default=4, help="Number of pings")
100
+ @click.option("-t", "--timeout", default=5, help="Timeout per ping (seconds)")
101
+ @click.pass_context
102
+ def ping(ctx, host, count, timeout):
103
+ """Ping a host."""
104
+ as_json = ctx.obj["json"]
105
+ try:
106
+ out = subprocess.run(
107
+ ["ping", "-c", str(count), "-W", str(timeout * 1000), host],
108
+ capture_output=True, text=True, timeout=count * timeout + 5
109
+ )
110
+ lines = out.stdout.strip().split("\n")
111
+ # Parse stats from last two lines
112
+ result = {"host": host, "count": count, "output": lines, "returncode": out.returncode}
113
+
114
+ # Try to parse summary
115
+ for line in lines:
116
+ if "packets transmitted" in line.lower() or "received" in line.lower():
117
+ result["summary"] = line.strip()
118
+ if "min/avg/max" in line or "round-trip" in line:
119
+ result["rtt"] = line.strip()
120
+
121
+ if as_json:
122
+ click.echo(_json.dumps(result, indent=2))
123
+ else:
124
+ click.echo(out.stdout)
125
+ if out.returncode != 0 and out.stderr:
126
+ click.echo(out.stderr, err=True)
127
+ except subprocess.TimeoutExpired:
128
+ msg = f"Ping to {host} timed out"
129
+ if as_json:
130
+ click.echo(_json.dumps({"host": host, "error": msg}))
131
+ else:
132
+ click.echo(msg, err=True)
133
+ sys.exit(1)
134
+ except Exception as e:
135
+ if as_json:
136
+ click.echo(_json.dumps({"host": host, "error": str(e)}))
137
+ else:
138
+ click.echo(f"Error: {e}", err=True)
139
+ sys.exit(1)
140
+
141
+
142
+ @cli.command()
143
+ @click.argument("url")
144
+ @click.option("--method", default="GET", help="HTTP method")
145
+ @click.option("--timeout", default=10, help="Timeout in seconds")
146
+ @click.option("--follow/--no-follow", default=True, help="Follow redirects")
147
+ @click.pass_context
148
+ def http(ctx, url, method, timeout, follow):
149
+ """Check HTTP endpoint status."""
150
+ as_json = ctx.obj["json"]
151
+ if not url.startswith("http"):
152
+ url = "https://" + url
153
+
154
+ result = {"url": url, "method": method}
155
+ start = time.monotonic()
156
+ try:
157
+ req = urllib.request.Request(url, method=method)
158
+ req.add_header("User-Agent", "netcheck-cli/0.1.0")
159
+
160
+ if not follow:
161
+ opener = urllib.request.build_opener(urllib.request.HTTPHandler, urllib.request.HTTPSHandler)
162
+ else:
163
+ opener = urllib.request.build_opener()
164
+
165
+ resp = opener.open(req, timeout=timeout)
166
+ elapsed = time.monotonic() - start
167
+ result["status"] = resp.status
168
+ result["reason"] = resp.reason
169
+ result["latency_ms"] = round(elapsed * 1000, 1)
170
+ result["headers"] = dict(resp.headers)
171
+ result["final_url"] = resp.url
172
+ result["ok"] = True
173
+
174
+ if not as_json:
175
+ click.echo(f"HTTP {method} {url}")
176
+ click.echo(f" Status: {resp.status} {resp.reason}")
177
+ click.echo(f" Latency: {result['latency_ms']}ms")
178
+ if resp.url != url:
179
+ click.echo(f" Redirected: {resp.url}")
180
+ ct = resp.headers.get("Content-Type", "")
181
+ if ct:
182
+ click.echo(f" Content-Type: {ct}")
183
+ server = resp.headers.get("Server", "")
184
+ if server:
185
+ click.echo(f" Server: {server}")
186
+ except urllib.error.HTTPError as e:
187
+ elapsed = time.monotonic() - start
188
+ result["status"] = e.code
189
+ result["reason"] = e.reason
190
+ result["latency_ms"] = round(elapsed * 1000, 1)
191
+ result["ok"] = False
192
+ if not as_json:
193
+ click.echo(f"HTTP {method} {url}")
194
+ click.echo(f" Status: {e.code} {e.reason}")
195
+ click.echo(f" Latency: {result['latency_ms']}ms")
196
+ except Exception as e:
197
+ elapsed = time.monotonic() - start
198
+ result["error"] = str(e)
199
+ result["latency_ms"] = round(elapsed * 1000, 1)
200
+ result["ok"] = False
201
+ if not as_json:
202
+ click.echo(f"HTTP {method} {url}")
203
+ click.echo(f" Error: {e}")
204
+ click.echo(f" Latency: {result['latency_ms']}ms")
205
+ sys.exit(1)
206
+
207
+ if as_json:
208
+ click.echo(_json.dumps(result, indent=2))
209
+
210
+
211
+ @cli.command()
212
+ @click.argument("hostname")
213
+ @click.option("--port", default=443, help="Port to connect to")
214
+ @click.pass_context
215
+ def cert(ctx, hostname, port):
216
+ """Check SSL/TLS certificate for a hostname."""
217
+ as_json = ctx.obj["json"]
218
+ result = {"hostname": hostname, "port": port}
219
+ try:
220
+ context = ssl.create_default_context()
221
+ with socket.create_connection((hostname, port), timeout=10) as sock:
222
+ with context.wrap_socket(sock, server_hostname=hostname) as ssock:
223
+ cert_info = ssock.getpeercert()
224
+ result["subject"] = dict(x[0] for x in cert_info.get("subject", ()))
225
+ result["issuer"] = dict(x[0] for x in cert_info.get("issuer", ()))
226
+ result["serial"] = cert_info.get("serialNumber", "")
227
+ result["version"] = cert_info.get("version", "")
228
+ result["notBefore"] = cert_info.get("notBefore", "")
229
+ result["notAfter"] = cert_info.get("notAfter", "")
230
+ result["protocol"] = ssock.version()
231
+
232
+ # Parse expiry
233
+ try:
234
+ expiry = datetime.strptime(cert_info["notAfter"], "%b %d %H:%M:%S %Y %Z")
235
+ expiry = expiry.replace(tzinfo=timezone.utc)
236
+ days_left = (expiry - datetime.now(timezone.utc)).days
237
+ result["days_until_expiry"] = days_left
238
+ result["expired"] = days_left < 0
239
+ except Exception:
240
+ pass
241
+
242
+ # SANs
243
+ sans = []
244
+ for type_val in cert_info.get("subjectAltName", ()):
245
+ sans.append(f"{type_val[0]}:{type_val[1]}")
246
+ result["san"] = sans
247
+
248
+ if not as_json:
249
+ cn = result["subject"].get("commonName", "N/A")
250
+ issuer_cn = result["issuer"].get("commonName", "N/A")
251
+ click.echo(f"SSL Certificate: {hostname}:{port}")
252
+ click.echo(f" Common Name: {cn}")
253
+ click.echo(f" Issuer: {issuer_cn}")
254
+ click.echo(f" Valid: {result['notBefore']} → {result['notAfter']}")
255
+ if "days_until_expiry" in result:
256
+ days = result["days_until_expiry"]
257
+ status = "⚠️ EXPIRED" if days < 0 else f"✅ {days} days left" if days > 30 else f"⚠️ {days} days left"
258
+ click.echo(f" Expiry: {status}")
259
+ click.echo(f" Protocol: {result['protocol']}")
260
+ if sans:
261
+ click.echo(f" SANs: {', '.join(s.split(':',1)[1] for s in sans[:5])}")
262
+ if len(sans) > 5:
263
+ click.echo(f" ... and {len(sans)-5} more")
264
+ except ssl.SSLCertVerificationError as e:
265
+ result["error"] = str(e)
266
+ result["valid"] = False
267
+ if not as_json:
268
+ click.echo(f"SSL Certificate: {hostname}:{port}")
269
+ click.echo(f" ❌ Verification failed: {e}")
270
+ except Exception as e:
271
+ result["error"] = str(e)
272
+ if not as_json:
273
+ click.echo(f"SSL Certificate: {hostname}:{port}")
274
+ click.echo(f" Error: {e}")
275
+ sys.exit(1)
276
+
277
+ if as_json:
278
+ click.echo(_json.dumps(result, indent=2))
279
+
280
+
281
+ @cli.command()
282
+ @click.argument("host")
283
+ @click.option("-p", "--port", default=443, help="Port to check")
284
+ @click.option("-n", "--count", default=5, help="Number of connections")
285
+ @click.pass_context
286
+ def latency(ctx, host, port, count):
287
+ """Measure TCP connection latency to host:port."""
288
+ as_json = ctx.obj["json"]
289
+ times = []
290
+ errors = 0
291
+ for _ in range(count):
292
+ start = time.monotonic()
293
+ try:
294
+ with socket.create_connection((host, port), timeout=5):
295
+ elapsed = (time.monotonic() - start) * 1000
296
+ times.append(round(elapsed, 2))
297
+ except Exception:
298
+ errors += 1
299
+ time.sleep(0.1)
300
+
301
+ result = {
302
+ "host": host,
303
+ "port": port,
304
+ "count": count,
305
+ "successful": len(times),
306
+ "errors": errors,
307
+ }
308
+ if times:
309
+ result["min_ms"] = min(times)
310
+ result["max_ms"] = max(times)
311
+ result["avg_ms"] = round(sum(times) / len(times), 2)
312
+ result["times_ms"] = times
313
+
314
+ if as_json:
315
+ click.echo(_json.dumps(result, indent=2))
316
+ else:
317
+ click.echo(f"TCP latency: {host}:{port} ({count} connections)")
318
+ if times:
319
+ click.echo(f" Min: {result['min_ms']}ms")
320
+ click.echo(f" Avg: {result['avg_ms']}ms")
321
+ click.echo(f" Max: {result['max_ms']}ms")
322
+ if errors:
323
+ click.echo(f" Errors: {errors}/{count}")
324
+ if not times:
325
+ click.echo(" All connections failed")
326
+ sys.exit(1)
327
+
328
+
329
+ @cli.command()
330
+ @click.argument("host")
331
+ @click.option("-p", "--ports", default="22,80,443,3000,5000,8080,8443", help="Comma-separated ports")
332
+ @click.option("-t", "--timeout", default=2, help="Timeout per port (seconds)")
333
+ @click.pass_context
334
+ def scan(ctx, host, ports, timeout):
335
+ """Quick port scan on common ports."""
336
+ as_json = ctx.obj["json"]
337
+ port_list = [int(p.strip()) for p in ports.split(",")]
338
+ results = []
339
+ for port in port_list:
340
+ try:
341
+ with socket.create_connection((host, port), timeout=timeout):
342
+ results.append({"port": port, "state": "open"})
343
+ except (ConnectionRefusedError, OSError):
344
+ results.append({"port": port, "state": "closed"})
345
+ except socket.timeout:
346
+ results.append({"port": port, "state": "filtered"})
347
+
348
+ if as_json:
349
+ click.echo(_json.dumps({"host": host, "ports": results}, indent=2))
350
+ else:
351
+ click.echo(f"Port scan: {host}")
352
+ for r in results:
353
+ icon = "✅" if r["state"] == "open" else "❌" if r["state"] == "closed" else "⏳"
354
+ click.echo(f" {icon} {r['port']:>5} {r['state']}")
355
+
356
+
357
+ @cli.command()
358
+ @click.pass_context
359
+ def ip(ctx):
360
+ """Show public and local IP addresses."""
361
+ as_json = ctx.obj["json"]
362
+ result = {}
363
+
364
+ # Local IP
365
+ try:
366
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
367
+ s.connect(("8.8.8.8", 80))
368
+ result["local_ip"] = s.getsockname()[0]
369
+ s.close()
370
+ except Exception:
371
+ result["local_ip"] = None
372
+
373
+ # Public IP
374
+ try:
375
+ req = urllib.request.Request("https://api.ipify.org?format=json")
376
+ req.add_header("User-Agent", "netcheck-cli/0.1.0")
377
+ resp = urllib.request.urlopen(req, timeout=5)
378
+ data = _json.loads(resp.read())
379
+ result["public_ip"] = data.get("ip")
380
+ except Exception:
381
+ result["public_ip"] = None
382
+
383
+ if as_json:
384
+ click.echo(_json.dumps(result, indent=2))
385
+ else:
386
+ click.echo(f" Local IP: {result.get('local_ip', 'unknown')}")
387
+ click.echo(f" Public IP: {result.get('public_ip', 'unknown')}")
388
+
389
+
390
+ if __name__ == "__main__":
391
+ cli()
@@ -0,0 +1,75 @@
1
+ Metadata-Version: 2.4
2
+ Name: netcheck-cli
3
+ Version: 0.1.0
4
+ Summary: Network diagnostics CLI — DNS, ping, HTTP check, SSL certs, latency
5
+ Author-email: Marcus <marcus.builds.things@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/marcusbuildsthings-droid/netcheck
8
+ Project-URL: Issues, https://github.com/marcusbuildsthings-droid/netcheck/issues
9
+ Keywords: network,dns,ping,ssl,diagnostics,cli
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Intended Audience :: System Administrators
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Topic :: System :: Networking
17
+ Classifier: Topic :: Utilities
18
+ Requires-Python: >=3.9
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: click>=8.0
22
+ Dynamic: license-file
23
+
24
+ # netcheck-cli
25
+
26
+ Network diagnostics from the command line — DNS lookup, ping, HTTP check, SSL cert info, latency, port scan, and IP lookup.
27
+
28
+ ## Install
29
+
30
+ ```bash
31
+ pip install netcheck-cli
32
+ ```
33
+
34
+ ## Usage
35
+
36
+ ```bash
37
+ # DNS lookup
38
+ netcheck dns example.com
39
+ netcheck dns example.com --type MX
40
+
41
+ # Ping
42
+ netcheck ping example.com -c 4
43
+
44
+ # HTTP endpoint check
45
+ netcheck http https://example.com
46
+ netcheck http api.example.com --method HEAD
47
+
48
+ # SSL certificate info
49
+ netcheck cert example.com
50
+ netcheck cert example.com --port 8443
51
+
52
+ # TCP latency measurement
53
+ netcheck latency example.com -n 10
54
+
55
+ # Port scan
56
+ netcheck scan example.com -p 80,443,8080
57
+
58
+ # Public + local IP
59
+ netcheck ip
60
+ ```
61
+
62
+ All commands support `--json` for machine-readable output:
63
+
64
+ ```bash
65
+ netcheck --json dns example.com
66
+ netcheck --json cert example.com
67
+ ```
68
+
69
+ ## For AI Agents
70
+
71
+ See [SKILL.md](SKILL.md) for agent-optimized documentation.
72
+
73
+ ## License
74
+
75
+ MIT
@@ -0,0 +1,11 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ netcheck/__init__.py
5
+ netcheck/cli.py
6
+ netcheck_cli.egg-info/PKG-INFO
7
+ netcheck_cli.egg-info/SOURCES.txt
8
+ netcheck_cli.egg-info/dependency_links.txt
9
+ netcheck_cli.egg-info/entry_points.txt
10
+ netcheck_cli.egg-info/requires.txt
11
+ netcheck_cli.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ netcheck = netcheck.cli:cli
@@ -0,0 +1 @@
1
+ click>=8.0
@@ -0,0 +1 @@
1
+ netcheck
@@ -0,0 +1,31 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "netcheck-cli"
7
+ version = "0.1.0"
8
+ description = "Network diagnostics CLI — DNS, ping, HTTP check, SSL certs, latency"
9
+ readme = "README.md"
10
+ license = {text = "MIT"}
11
+ requires-python = ">=3.9"
12
+ authors = [{name = "Marcus", email = "marcus.builds.things@gmail.com"}]
13
+ keywords = ["network", "dns", "ping", "ssl", "diagnostics", "cli"]
14
+ classifiers = [
15
+ "Development Status :: 4 - Beta",
16
+ "Environment :: Console",
17
+ "Intended Audience :: Developers",
18
+ "Intended Audience :: System Administrators",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Programming Language :: Python :: 3",
21
+ "Topic :: System :: Networking",
22
+ "Topic :: Utilities",
23
+ ]
24
+ dependencies = ["click>=8.0"]
25
+
26
+ [project.scripts]
27
+ netcheck = "netcheck.cli:cli"
28
+
29
+ [project.urls]
30
+ Homepage = "https://github.com/marcusbuildsthings-droid/netcheck"
31
+ Issues = "https://github.com/marcusbuildsthings-droid/netcheck/issues"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+