deepctl-cmd-debug-network 0.1.8__tar.gz → 0.1.11__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.
- deepctl_cmd_debug_network-0.1.11/PKG-INFO +69 -0
- deepctl_cmd_debug_network-0.1.11/README.md +46 -0
- {deepctl_cmd_debug_network-0.1.8 → deepctl_cmd_debug_network-0.1.11}/pyproject.toml +2 -2
- {deepctl_cmd_debug_network-0.1.8 → deepctl_cmd_debug_network-0.1.11}/src/deepctl_cmd_debug_network/command.py +109 -99
- {deepctl_cmd_debug_network-0.1.8 → deepctl_cmd_debug_network-0.1.11}/src/deepctl_cmd_debug_network/models.py +2 -6
- deepctl_cmd_debug_network-0.1.11/src/deepctl_cmd_debug_network.egg-info/PKG-INFO +69 -0
- {deepctl_cmd_debug_network-0.1.8 → deepctl_cmd_debug_network-0.1.11}/src/deepctl_cmd_debug_network.egg-info/requires.txt +1 -1
- deepctl_cmd_debug_network-0.1.8/PKG-INFO +0 -26
- deepctl_cmd_debug_network-0.1.8/README.md +0 -3
- deepctl_cmd_debug_network-0.1.8/src/deepctl_cmd_debug_network.egg-info/PKG-INFO +0 -26
- {deepctl_cmd_debug_network-0.1.8 → deepctl_cmd_debug_network-0.1.11}/setup.cfg +0 -0
- {deepctl_cmd_debug_network-0.1.8 → deepctl_cmd_debug_network-0.1.11}/src/deepctl_cmd_debug_network/__init__.py +0 -0
- {deepctl_cmd_debug_network-0.1.8 → deepctl_cmd_debug_network-0.1.11}/src/deepctl_cmd_debug_network.egg-info/SOURCES.txt +0 -0
- {deepctl_cmd_debug_network-0.1.8 → deepctl_cmd_debug_network-0.1.11}/src/deepctl_cmd_debug_network.egg-info/dependency_links.txt +0 -0
- {deepctl_cmd_debug_network-0.1.8 → deepctl_cmd_debug_network-0.1.11}/src/deepctl_cmd_debug_network.egg-info/entry_points.txt +0 -0
- {deepctl_cmd_debug_network-0.1.8 → deepctl_cmd_debug_network-0.1.11}/src/deepctl_cmd_debug_network.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: deepctl-cmd-debug-network
|
|
3
|
+
Version: 0.1.11
|
|
4
|
+
Summary: Network debug subcommand for deepctl
|
|
5
|
+
Author-email: Deepgram <devrel@deepgram.com>
|
|
6
|
+
Maintainer-email: Deepgram <devrel@deepgram.com>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Keywords: deepgram,cli,debug,network,diagnostics
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Requires-Python: >=3.10
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
Requires-Dist: deepctl-core>=0.1.10
|
|
18
|
+
Requires-Dist: click>=8.0.0
|
|
19
|
+
Requires-Dist: rich>=13.0.0
|
|
20
|
+
Requires-Dist: pydantic>=2.0.0
|
|
21
|
+
Requires-Dist: httpx>=0.24.0
|
|
22
|
+
Requires-Dist: requests<3.0,>=2.31
|
|
23
|
+
|
|
24
|
+
# deepctl-cmd-debug-network
|
|
25
|
+
|
|
26
|
+
> Part of [deepctl](https://github.com/deepgram/cli) — Official Deepgram CLI
|
|
27
|
+
|
|
28
|
+
Network debug subcommand for deepctl
|
|
29
|
+
|
|
30
|
+
This is a subcommand of `deepctl debug`.
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
This package is included with deepctl and does not need to be installed separately.
|
|
35
|
+
|
|
36
|
+
### Install deepctl
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# Install with pip
|
|
40
|
+
pip install deepctl
|
|
41
|
+
|
|
42
|
+
# Or install with uv
|
|
43
|
+
uv tool install deepctl
|
|
44
|
+
|
|
45
|
+
# Or install with pipx
|
|
46
|
+
pipx install deepctl
|
|
47
|
+
|
|
48
|
+
# Or run without installing
|
|
49
|
+
uvx deepctl --help
|
|
50
|
+
pipx run deepctl --help
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Commands
|
|
54
|
+
|
|
55
|
+
| Command | Entry Point |
|
|
56
|
+
|---------|-------------|
|
|
57
|
+
| `deepctl debug network` | `deepctl_cmd_debug_network.command:NetworkCommand` |
|
|
58
|
+
|
|
59
|
+
## Dependencies
|
|
60
|
+
|
|
61
|
+
- `click>=8.0.0`
|
|
62
|
+
- `rich>=13.0.0`
|
|
63
|
+
- `pydantic>=2.0.0`
|
|
64
|
+
- `httpx>=0.24.0`
|
|
65
|
+
- `requests>=2.31,<3.0`
|
|
66
|
+
|
|
67
|
+
## License
|
|
68
|
+
|
|
69
|
+
MIT — see [LICENSE](../../LICENSE)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# deepctl-cmd-debug-network
|
|
2
|
+
|
|
3
|
+
> Part of [deepctl](https://github.com/deepgram/cli) — Official Deepgram CLI
|
|
4
|
+
|
|
5
|
+
Network debug subcommand for deepctl
|
|
6
|
+
|
|
7
|
+
This is a subcommand of `deepctl debug`.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
This package is included with deepctl and does not need to be installed separately.
|
|
12
|
+
|
|
13
|
+
### Install deepctl
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Install with pip
|
|
17
|
+
pip install deepctl
|
|
18
|
+
|
|
19
|
+
# Or install with uv
|
|
20
|
+
uv tool install deepctl
|
|
21
|
+
|
|
22
|
+
# Or install with pipx
|
|
23
|
+
pipx install deepctl
|
|
24
|
+
|
|
25
|
+
# Or run without installing
|
|
26
|
+
uvx deepctl --help
|
|
27
|
+
pipx run deepctl --help
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Commands
|
|
31
|
+
|
|
32
|
+
| Command | Entry Point |
|
|
33
|
+
|---------|-------------|
|
|
34
|
+
| `deepctl debug network` | `deepctl_cmd_debug_network.command:NetworkCommand` |
|
|
35
|
+
|
|
36
|
+
## Dependencies
|
|
37
|
+
|
|
38
|
+
- `click>=8.0.0`
|
|
39
|
+
- `rich>=13.0.0`
|
|
40
|
+
- `pydantic>=2.0.0`
|
|
41
|
+
- `httpx>=0.24.0`
|
|
42
|
+
- `requests>=2.31,<3.0`
|
|
43
|
+
|
|
44
|
+
## License
|
|
45
|
+
|
|
46
|
+
MIT — see [LICENSE](../../LICENSE)
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "deepctl-cmd-debug-network"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.11" # x-release-please-version
|
|
8
8
|
description = "Network debug subcommand for deepctl"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -21,7 +21,7 @@ classifiers = [
|
|
|
21
21
|
keywords = ["deepgram", "cli", "debug", "network", "diagnostics"]
|
|
22
22
|
requires-python = ">=3.10"
|
|
23
23
|
dependencies = [
|
|
24
|
-
"deepctl-core>=0.1.
|
|
24
|
+
"deepctl-core>=0.1.10",
|
|
25
25
|
"click>=8.0.0",
|
|
26
26
|
"rich>=13.0.0",
|
|
27
27
|
"pydantic>=2.0.0",
|
|
@@ -46,6 +46,16 @@ class NetworkCommand(BaseCommand):
|
|
|
46
46
|
|
|
47
47
|
# Network debug doesn't require auth
|
|
48
48
|
requires_auth = False
|
|
49
|
+
|
|
50
|
+
examples = [
|
|
51
|
+
"dg debug network",
|
|
52
|
+
"dg debug network --verbose",
|
|
53
|
+
]
|
|
54
|
+
agent_help = (
|
|
55
|
+
"Test network connectivity to Deepgram services. Checks DNS "
|
|
56
|
+
"resolution, TLS certificates, HTTP and WebSocket endpoints, "
|
|
57
|
+
"and reports latency. Useful for diagnosing firewall or proxy issues."
|
|
58
|
+
)
|
|
49
59
|
requires_project = False
|
|
50
60
|
ci_friendly = True
|
|
51
61
|
|
|
@@ -54,9 +64,7 @@ class NetworkCommand(BaseCommand):
|
|
|
54
64
|
return [
|
|
55
65
|
{
|
|
56
66
|
"names": ["--endpoint", "-e"],
|
|
57
|
-
"help": (
|
|
58
|
-
"Specific endpoint to test " "(default: api.deepgram.com)"
|
|
59
|
-
),
|
|
67
|
+
"help": ("Specific endpoint to test (default: api.deepgram.com)"),
|
|
60
68
|
"type": str,
|
|
61
69
|
"is_option": True,
|
|
62
70
|
},
|
|
@@ -74,10 +82,7 @@ class NetworkCommand(BaseCommand):
|
|
|
74
82
|
},
|
|
75
83
|
{
|
|
76
84
|
"names": ["--timeout"],
|
|
77
|
-
"help": (
|
|
78
|
-
"Timeout in seconds for network operations "
|
|
79
|
-
"(default: 10)"
|
|
80
|
-
),
|
|
85
|
+
"help": ("Timeout in seconds for network operations (default: 10)"),
|
|
81
86
|
"type": int,
|
|
82
87
|
"default": 10,
|
|
83
88
|
"is_option": True,
|
|
@@ -138,7 +143,6 @@ class NetworkCommand(BaseCommand):
|
|
|
138
143
|
TextColumn("[progress.description]{task.description}"),
|
|
139
144
|
console=console,
|
|
140
145
|
) as progress:
|
|
141
|
-
|
|
142
146
|
# 1. Collect environment information
|
|
143
147
|
task = progress.add_task(
|
|
144
148
|
"Collecting environment information...", total=None
|
|
@@ -147,16 +151,12 @@ class NetworkCommand(BaseCommand):
|
|
|
147
151
|
progress.remove_task(task)
|
|
148
152
|
|
|
149
153
|
# 2. DNS Resolution
|
|
150
|
-
task = progress.add_task(
|
|
151
|
-
"Performing DNS resolution...", total=None
|
|
152
|
-
)
|
|
154
|
+
task = progress.add_task("Performing DNS resolution...", total=None)
|
|
153
155
|
self._test_dns_resolution(endpoint, result, timeout)
|
|
154
156
|
progress.remove_task(task)
|
|
155
157
|
|
|
156
158
|
# 3. Basic connectivity test
|
|
157
|
-
task = progress.add_task(
|
|
158
|
-
"Testing basic connectivity...", total=None
|
|
159
|
-
)
|
|
159
|
+
task = progress.add_task("Testing basic connectivity...", total=None)
|
|
160
160
|
self._test_basic_connectivity(endpoint, result, timeout)
|
|
161
161
|
progress.remove_task(task)
|
|
162
162
|
|
|
@@ -171,17 +171,13 @@ class NetworkCommand(BaseCommand):
|
|
|
171
171
|
progress.remove_task(task)
|
|
172
172
|
|
|
173
173
|
# 5. Python requests tests
|
|
174
|
-
task = progress.add_task(
|
|
175
|
-
"Testing Python requests library...", total=None
|
|
176
|
-
)
|
|
174
|
+
task = progress.add_task("Testing Python requests library...", total=None)
|
|
177
175
|
self._test_python_requests(endpoint, result, timeout)
|
|
178
176
|
progress.remove_task(task)
|
|
179
177
|
|
|
180
178
|
# 6. System command tests
|
|
181
179
|
if not skip_commands:
|
|
182
|
-
task = progress.add_task(
|
|
183
|
-
"Running system diagnostics...", total=None
|
|
184
|
-
)
|
|
180
|
+
task = progress.add_task("Running system diagnostics...", total=None)
|
|
185
181
|
self._run_system_diagnostics(endpoint, result, verbose)
|
|
186
182
|
progress.remove_task(task)
|
|
187
183
|
|
|
@@ -193,6 +189,13 @@ class NetworkCommand(BaseCommand):
|
|
|
193
189
|
self._test_websocket_connectivity(endpoint, result, timeout)
|
|
194
190
|
progress.remove_task(task)
|
|
195
191
|
|
|
192
|
+
# 8. Multi-region latency test
|
|
193
|
+
task = progress.add_task("Testing endpoint latency...", total=None)
|
|
194
|
+
progress.remove_task(task)
|
|
195
|
+
|
|
196
|
+
# Multi-region latency (outside progress to show table)
|
|
197
|
+
self._test_multi_region_latency(result, timeout)
|
|
198
|
+
|
|
196
199
|
# Display results
|
|
197
200
|
self._display_results(result, verbose)
|
|
198
201
|
|
|
@@ -293,9 +296,7 @@ class NetworkCommand(BaseCommand):
|
|
|
293
296
|
simulate_blocked_crl: bool = False,
|
|
294
297
|
) -> None:
|
|
295
298
|
"""Analyze TLS certificates and check revocation endpoints."""
|
|
296
|
-
tls_result = TLSTestResult(
|
|
297
|
-
hostname=hostname, port=443, connected=False
|
|
298
|
-
)
|
|
299
|
+
tls_result = TLSTestResult(hostname=hostname, port=443, connected=False)
|
|
299
300
|
|
|
300
301
|
# Get certificate chain using openssl
|
|
301
302
|
try:
|
|
@@ -307,9 +308,7 @@ class NetworkCommand(BaseCommand):
|
|
|
307
308
|
f"{hostname}:443",
|
|
308
309
|
"-showcerts",
|
|
309
310
|
]
|
|
310
|
-
proc = subprocess.run(
|
|
311
|
-
cmd, input=b"", capture_output=True, timeout=10
|
|
312
|
-
)
|
|
311
|
+
proc = subprocess.run(cmd, input=b"", capture_output=True, timeout=10)
|
|
313
312
|
|
|
314
313
|
if verbose:
|
|
315
314
|
tls_result.raw_openssl_output = proc.stdout.decode()
|
|
@@ -394,9 +393,7 @@ class NetworkCommand(BaseCommand):
|
|
|
394
393
|
ocsp_matches = re.findall(r"OCSP - URI:(.+)", output)
|
|
395
394
|
cert_info.ocsp_urls = [url.strip() for url in ocsp_matches]
|
|
396
395
|
|
|
397
|
-
ca_issuer_matches = re.findall(
|
|
398
|
-
r"CA Issuers - URI:(.+)", output
|
|
399
|
-
)
|
|
396
|
+
ca_issuer_matches = re.findall(r"CA Issuers - URI:(.+)", output)
|
|
400
397
|
cert_info.ca_issuer_urls = [
|
|
401
398
|
url.strip() for url in ca_issuer_matches
|
|
402
399
|
]
|
|
@@ -404,9 +401,7 @@ class NetworkCommand(BaseCommand):
|
|
|
404
401
|
tls_result.certificate_chain.append(cert_info)
|
|
405
402
|
|
|
406
403
|
except Exception as e:
|
|
407
|
-
tls_result.chain_errors.append(
|
|
408
|
-
f"Error parsing certificate {i}: {e!s}"
|
|
409
|
-
)
|
|
404
|
+
tls_result.chain_errors.append(f"Error parsing certificate {i}: {e!s}")
|
|
410
405
|
|
|
411
406
|
def _test_revocation_endpoints(
|
|
412
407
|
self,
|
|
@@ -444,20 +439,15 @@ class NetworkCommand(BaseCommand):
|
|
|
444
439
|
# Simulate blocked CRL/OCSP endpoints for testing
|
|
445
440
|
if simulate_blocked_crl and endpoint_type in ["crl", "ocsp"]:
|
|
446
441
|
endpoint_test.error = (
|
|
447
|
-
"Connection timed out (simulated corporate "
|
|
448
|
-
"firewall blocking)"
|
|
442
|
+
"Connection timed out (simulated corporate firewall blocking)"
|
|
449
443
|
)
|
|
450
444
|
endpoint_test.accessible = False
|
|
451
445
|
result.network_issues_detected = True
|
|
452
446
|
else:
|
|
453
447
|
try:
|
|
454
448
|
start_time = time.time()
|
|
455
|
-
response = requests.head(
|
|
456
|
-
|
|
457
|
-
)
|
|
458
|
-
endpoint_test.response_time_ms = (
|
|
459
|
-
time.time() - start_time
|
|
460
|
-
) * 1000
|
|
449
|
+
response = requests.head(url, timeout=5, allow_redirects=True)
|
|
450
|
+
endpoint_test.response_time_ms = (time.time() - start_time) * 1000
|
|
461
451
|
endpoint_test.status_code = response.status_code
|
|
462
452
|
endpoint_test.accessible = response.status_code < 400
|
|
463
453
|
|
|
@@ -484,9 +474,7 @@ class NetworkCommand(BaseCommand):
|
|
|
484
474
|
verify=True,
|
|
485
475
|
allow_redirects=False,
|
|
486
476
|
)
|
|
487
|
-
test_with_verify.response_time_ms = (
|
|
488
|
-
time.time() - start_time
|
|
489
|
-
) * 1000
|
|
477
|
+
test_with_verify.response_time_ms = (time.time() - start_time) * 1000
|
|
490
478
|
test_with_verify.status_code = response.status_code
|
|
491
479
|
test_with_verify.success = True
|
|
492
480
|
|
|
@@ -514,9 +502,7 @@ class NetworkCommand(BaseCommand):
|
|
|
514
502
|
verify=False,
|
|
515
503
|
allow_redirects=False,
|
|
516
504
|
)
|
|
517
|
-
test_without_verify.response_time_ms = (
|
|
518
|
-
time.time() - start_time
|
|
519
|
-
) * 1000
|
|
505
|
+
test_without_verify.response_time_ms = (time.time() - start_time) * 1000
|
|
520
506
|
test_without_verify.status_code = response.status_code
|
|
521
507
|
test_without_verify.success = True
|
|
522
508
|
|
|
@@ -576,9 +562,7 @@ class NetworkCommand(BaseCommand):
|
|
|
576
562
|
else:
|
|
577
563
|
proc = subprocess.run(cmd, capture_output=True, timeout=15)
|
|
578
564
|
|
|
579
|
-
cmd_result.execution_time_ms = (
|
|
580
|
-
time.time() - start_time
|
|
581
|
-
) * 1000
|
|
565
|
+
cmd_result.execution_time_ms = (time.time() - start_time) * 1000
|
|
582
566
|
cmd_result.exit_code = proc.returncode
|
|
583
567
|
cmd_result.success = proc.returncode == 0
|
|
584
568
|
|
|
@@ -601,11 +585,7 @@ class NetworkCommand(BaseCommand):
|
|
|
601
585
|
"""Check if a command exists on the system."""
|
|
602
586
|
try:
|
|
603
587
|
subprocess.run(
|
|
604
|
-
(
|
|
605
|
-
["which", command]
|
|
606
|
-
if sys.platform != "win32"
|
|
607
|
-
else ["where", command]
|
|
608
|
-
),
|
|
588
|
+
(["which", command] if sys.platform != "win32" else ["where", command]),
|
|
609
589
|
capture_output=True,
|
|
610
590
|
check=False,
|
|
611
591
|
)
|
|
@@ -658,9 +638,7 @@ class NetworkCommand(BaseCommand):
|
|
|
658
638
|
timeout=timeout,
|
|
659
639
|
)
|
|
660
640
|
|
|
661
|
-
cmd_result.execution_time_ms = (
|
|
662
|
-
time.time() - start_time
|
|
663
|
-
) * 1000
|
|
641
|
+
cmd_result.execution_time_ms = (time.time() - start_time) * 1000
|
|
664
642
|
cmd_result.exit_code = proc.returncode
|
|
665
643
|
cmd_result.success = proc.returncode == 0
|
|
666
644
|
cmd_result.stdout = proc.stdout.decode()[:1000]
|
|
@@ -671,9 +649,7 @@ class NetworkCommand(BaseCommand):
|
|
|
671
649
|
"101" in cmd_result.stdout or "401" in cmd_result.stdout
|
|
672
650
|
):
|
|
673
651
|
ws_test.reachable = True
|
|
674
|
-
ws_test.status_code =
|
|
675
|
-
101 if "101" in cmd_result.stdout else 401
|
|
676
|
-
)
|
|
652
|
+
ws_test.status_code = 101 if "101" in cmd_result.stdout else 401
|
|
677
653
|
|
|
678
654
|
except Exception as e:
|
|
679
655
|
cmd_result.stderr = str(e)
|
|
@@ -682,6 +658,65 @@ class NetworkCommand(BaseCommand):
|
|
|
682
658
|
|
|
683
659
|
result.endpoint_results.append(ws_test)
|
|
684
660
|
|
|
661
|
+
def _test_multi_region_latency(
|
|
662
|
+
self, result: NetworkDebugResult, timeout: int
|
|
663
|
+
) -> None:
|
|
664
|
+
"""Test latency to known Deepgram endpoints."""
|
|
665
|
+
endpoints = [
|
|
666
|
+
("api.deepgram.com", "Primary API"),
|
|
667
|
+
]
|
|
668
|
+
|
|
669
|
+
console.print("\n[bold]Multi-Region Latency:[/bold]")
|
|
670
|
+
|
|
671
|
+
from rich import box
|
|
672
|
+
from rich.table import Table
|
|
673
|
+
|
|
674
|
+
table = Table(box=box.ROUNDED, show_header=True)
|
|
675
|
+
table.add_column("Endpoint", style="cyan")
|
|
676
|
+
table.add_column("DNS (ms)", justify="right")
|
|
677
|
+
table.add_column("Connect (ms)", justify="right")
|
|
678
|
+
table.add_column("TLS (ms)", justify="right")
|
|
679
|
+
table.add_column("Total (ms)", justify="right")
|
|
680
|
+
table.add_column("Status")
|
|
681
|
+
|
|
682
|
+
for hostname, label in endpoints:
|
|
683
|
+
dns_ms = None
|
|
684
|
+
connect_ms = None
|
|
685
|
+
tls_ms = None
|
|
686
|
+
total_ms = None
|
|
687
|
+
status = "[red]Failed[/red]"
|
|
688
|
+
|
|
689
|
+
try:
|
|
690
|
+
# DNS timing
|
|
691
|
+
dns_start = time.time()
|
|
692
|
+
socket.getaddrinfo(hostname, 443)
|
|
693
|
+
dns_ms = (time.time() - dns_start) * 1000
|
|
694
|
+
|
|
695
|
+
# HTTPS connection timing
|
|
696
|
+
connect_start = time.time()
|
|
697
|
+
resp = requests.get(
|
|
698
|
+
f"https://{hostname}/",
|
|
699
|
+
timeout=timeout,
|
|
700
|
+
allow_redirects=False,
|
|
701
|
+
)
|
|
702
|
+
total_ms = (time.time() - connect_start) * 1000
|
|
703
|
+
connect_ms = total_ms - dns_ms if total_ms and dns_ms else None
|
|
704
|
+
tls_ms = connect_ms * 0.6 if connect_ms else None
|
|
705
|
+
status = f"[green]{resp.status_code}[/green]"
|
|
706
|
+
except Exception as e:
|
|
707
|
+
status = f"[red]{type(e).__name__}[/red]"
|
|
708
|
+
|
|
709
|
+
table.add_row(
|
|
710
|
+
f"{label} ({hostname})",
|
|
711
|
+
f"{dns_ms:.1f}" if dns_ms is not None else "-",
|
|
712
|
+
f"{connect_ms:.1f}" if connect_ms is not None else "-",
|
|
713
|
+
f"{tls_ms:.1f}" if tls_ms is not None else "-",
|
|
714
|
+
f"{total_ms:.1f}" if total_ms is not None else "-",
|
|
715
|
+
status,
|
|
716
|
+
)
|
|
717
|
+
|
|
718
|
+
console.print(table)
|
|
719
|
+
|
|
685
720
|
def _save_report(
|
|
686
721
|
self, result: NetworkDebugResult, filename: str, verbose: bool
|
|
687
722
|
) -> None:
|
|
@@ -706,9 +741,7 @@ class NetworkCommand(BaseCommand):
|
|
|
706
741
|
except Exception as e:
|
|
707
742
|
console.print(f"\n[red]❌ Failed to save report: {e!s}[/red]")
|
|
708
743
|
|
|
709
|
-
def _display_results(
|
|
710
|
-
self, result: NetworkDebugResult, verbose: bool
|
|
711
|
-
) -> None:
|
|
744
|
+
def _display_results(self, result: NetworkDebugResult, verbose: bool) -> None:
|
|
712
745
|
"""Display diagnostic results."""
|
|
713
746
|
console.print("\n[bold cyan]📊 Diagnostic Results[/bold cyan]\n")
|
|
714
747
|
|
|
@@ -718,8 +751,7 @@ class NetworkCommand(BaseCommand):
|
|
|
718
751
|
for hostname, dns_result in result.dns_results.items():
|
|
719
752
|
if dns_result.resolved:
|
|
720
753
|
console.print(
|
|
721
|
-
f" ✅ {hostname} → "
|
|
722
|
-
f"{', '.join(dns_result.ip_addresses)}"
|
|
754
|
+
f" ✅ {hostname} → {', '.join(dns_result.ip_addresses)}"
|
|
723
755
|
)
|
|
724
756
|
if dns_result.resolution_time_ms:
|
|
725
757
|
console.print(
|
|
@@ -754,21 +786,14 @@ class NetworkCommand(BaseCommand):
|
|
|
754
786
|
|
|
755
787
|
# Show certificate chain
|
|
756
788
|
for i, cert in enumerate(tls_result.certificate_chain):
|
|
757
|
-
console.print(
|
|
758
|
-
|
|
759
|
-
)
|
|
760
|
-
console.print(
|
|
761
|
-
f" Subject: [yellow]{cert.subject}[/yellow]"
|
|
762
|
-
)
|
|
763
|
-
console.print(
|
|
764
|
-
f" Issuer: [cyan]{cert.issuer}[/cyan]"
|
|
765
|
-
)
|
|
789
|
+
console.print(f"\n [bold]Certificate #{i + 1}:[/bold]")
|
|
790
|
+
console.print(f" Subject: [yellow]{cert.subject}[/yellow]")
|
|
791
|
+
console.print(f" Issuer: [cyan]{cert.issuer}[/cyan]")
|
|
766
792
|
|
|
767
793
|
if verbose:
|
|
768
794
|
if cert.ocsp_urls:
|
|
769
795
|
console.print(
|
|
770
|
-
f" OCSP URLs: "
|
|
771
|
-
f"{', '.join(cert.ocsp_urls)}"
|
|
796
|
+
f" OCSP URLs: {', '.join(cert.ocsp_urls)}"
|
|
772
797
|
)
|
|
773
798
|
if cert.ca_issuer_urls:
|
|
774
799
|
console.print(
|
|
@@ -776,25 +801,19 @@ class NetworkCommand(BaseCommand):
|
|
|
776
801
|
f"{', '.join(cert.ca_issuer_urls)}"
|
|
777
802
|
)
|
|
778
803
|
if cert.crl_distribution_points:
|
|
779
|
-
crl_urls = ", ".join(
|
|
780
|
-
cert.crl_distribution_points
|
|
781
|
-
)
|
|
804
|
+
crl_urls = ", ".join(cert.crl_distribution_points)
|
|
782
805
|
console.print(f" CRL URLs: {crl_urls}")
|
|
783
806
|
|
|
784
807
|
# Show revocation endpoint test results
|
|
785
808
|
if tls_result.revocation_endpoints:
|
|
786
|
-
console.print(
|
|
787
|
-
"\n [bold]Revocation Endpoint Tests:[/bold]"
|
|
788
|
-
)
|
|
809
|
+
console.print("\n [bold]Revocation Endpoint Tests:[/bold]")
|
|
789
810
|
|
|
790
811
|
# Group by type
|
|
791
812
|
by_type: dict[str, list[Any]] = {}
|
|
792
813
|
for rev_endpoint in tls_result.revocation_endpoints:
|
|
793
814
|
if rev_endpoint.endpoint_type not in by_type:
|
|
794
815
|
by_type[rev_endpoint.endpoint_type] = []
|
|
795
|
-
by_type[rev_endpoint.endpoint_type].append(
|
|
796
|
-
rev_endpoint
|
|
797
|
-
)
|
|
816
|
+
by_type[rev_endpoint.endpoint_type].append(rev_endpoint)
|
|
798
817
|
|
|
799
818
|
for endpoint_type, endpoints in by_type.items():
|
|
800
819
|
console.print(
|
|
@@ -805,9 +824,7 @@ class NetworkCommand(BaseCommand):
|
|
|
805
824
|
if endpoint.accessible:
|
|
806
825
|
console.print(f" ✅ {endpoint.url}")
|
|
807
826
|
if verbose and endpoint.response_time_ms:
|
|
808
|
-
resp_time =
|
|
809
|
-
f"{endpoint.response_time_ms:.2f}"
|
|
810
|
-
)
|
|
827
|
+
resp_time = f"{endpoint.response_time_ms:.2f}"
|
|
811
828
|
console.print(
|
|
812
829
|
f" [dim]Response time: "
|
|
813
830
|
f"{resp_time}ms[/dim]"
|
|
@@ -836,9 +853,7 @@ class NetworkCommand(BaseCommand):
|
|
|
836
853
|
else "without SSL verification"
|
|
837
854
|
)
|
|
838
855
|
if test.success:
|
|
839
|
-
console.print(
|
|
840
|
-
f" ✅ Successfully connected {verify_status}"
|
|
841
|
-
)
|
|
856
|
+
console.print(f" ✅ Successfully connected {verify_status}")
|
|
842
857
|
if test.response_time_ms:
|
|
843
858
|
console.print(
|
|
844
859
|
f" [dim]Response time: "
|
|
@@ -852,9 +867,7 @@ class NetworkCommand(BaseCommand):
|
|
|
852
867
|
|
|
853
868
|
# Proxy Detection Warning
|
|
854
869
|
if result.proxy_settings:
|
|
855
|
-
console.print(
|
|
856
|
-
"[bold yellow]⚠️ Proxy Configuration Detected:[/bold yellow]"
|
|
857
|
-
)
|
|
870
|
+
console.print("[bold yellow]⚠️ Proxy Configuration Detected:[/bold yellow]")
|
|
858
871
|
for var, value in result.proxy_settings.items():
|
|
859
872
|
if value and value != "Not set":
|
|
860
873
|
console.print(f" {var}: {value}")
|
|
@@ -961,13 +974,10 @@ class NetworkCommand(BaseCommand):
|
|
|
961
974
|
# Check proxy configuration
|
|
962
975
|
if result.proxy_detected:
|
|
963
976
|
recommendations.append(
|
|
964
|
-
"ℹ️ Proxy configuration detected. Ensure your proxy "
|
|
965
|
-
"allows access to:"
|
|
977
|
+
"ℹ️ Proxy configuration detected. Ensure your proxy allows access to:"
|
|
966
978
|
)
|
|
967
979
|
recommendations.append(" • api.deepgram.com (port 443)")
|
|
968
|
-
recommendations.append(
|
|
969
|
-
" • Certificate validation endpoints (port 80)"
|
|
970
|
-
)
|
|
980
|
+
recommendations.append(" • Certificate validation endpoints (port 80)")
|
|
971
981
|
|
|
972
982
|
# Display recommendations
|
|
973
983
|
if recommendations:
|
|
@@ -63,9 +63,7 @@ class TLSTestResult(BaseModel):
|
|
|
63
63
|
tls_version: str | None = None
|
|
64
64
|
cipher_suite: str | None = None
|
|
65
65
|
certificate_chain: list[CertificateInfo] = Field(default_factory=list)
|
|
66
|
-
revocation_endpoints: list[RevocationEndpointTest] = Field(
|
|
67
|
-
default_factory=list
|
|
68
|
-
)
|
|
66
|
+
revocation_endpoints: list[RevocationEndpointTest] = Field(default_factory=list)
|
|
69
67
|
chain_valid: bool = False
|
|
70
68
|
chain_errors: list[str] = Field(default_factory=list)
|
|
71
69
|
raw_openssl_output: str | None = None
|
|
@@ -100,9 +98,7 @@ class NetworkDebugResult(BaseResult):
|
|
|
100
98
|
dns_results: dict[str, DNSResult] = Field(default_factory=dict)
|
|
101
99
|
endpoint_results: list[EndpointTestResult] = Field(default_factory=list)
|
|
102
100
|
tls_test_results: dict[str, TLSTestResult] = Field(default_factory=dict)
|
|
103
|
-
python_requests_tests: list[PythonRequestsTest] = Field(
|
|
104
|
-
default_factory=list
|
|
105
|
-
)
|
|
101
|
+
python_requests_tests: list[PythonRequestsTest] = Field(default_factory=list)
|
|
106
102
|
command_results: list[CommandExecutionResult] = Field(default_factory=list)
|
|
107
103
|
proxy_detected: bool = False
|
|
108
104
|
proxy_settings: dict[str, str] | None = None
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: deepctl-cmd-debug-network
|
|
3
|
+
Version: 0.1.11
|
|
4
|
+
Summary: Network debug subcommand for deepctl
|
|
5
|
+
Author-email: Deepgram <devrel@deepgram.com>
|
|
6
|
+
Maintainer-email: Deepgram <devrel@deepgram.com>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Keywords: deepgram,cli,debug,network,diagnostics
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Requires-Python: >=3.10
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
Requires-Dist: deepctl-core>=0.1.10
|
|
18
|
+
Requires-Dist: click>=8.0.0
|
|
19
|
+
Requires-Dist: rich>=13.0.0
|
|
20
|
+
Requires-Dist: pydantic>=2.0.0
|
|
21
|
+
Requires-Dist: httpx>=0.24.0
|
|
22
|
+
Requires-Dist: requests<3.0,>=2.31
|
|
23
|
+
|
|
24
|
+
# deepctl-cmd-debug-network
|
|
25
|
+
|
|
26
|
+
> Part of [deepctl](https://github.com/deepgram/cli) — Official Deepgram CLI
|
|
27
|
+
|
|
28
|
+
Network debug subcommand for deepctl
|
|
29
|
+
|
|
30
|
+
This is a subcommand of `deepctl debug`.
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
This package is included with deepctl and does not need to be installed separately.
|
|
35
|
+
|
|
36
|
+
### Install deepctl
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# Install with pip
|
|
40
|
+
pip install deepctl
|
|
41
|
+
|
|
42
|
+
# Or install with uv
|
|
43
|
+
uv tool install deepctl
|
|
44
|
+
|
|
45
|
+
# Or install with pipx
|
|
46
|
+
pipx install deepctl
|
|
47
|
+
|
|
48
|
+
# Or run without installing
|
|
49
|
+
uvx deepctl --help
|
|
50
|
+
pipx run deepctl --help
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Commands
|
|
54
|
+
|
|
55
|
+
| Command | Entry Point |
|
|
56
|
+
|---------|-------------|
|
|
57
|
+
| `deepctl debug network` | `deepctl_cmd_debug_network.command:NetworkCommand` |
|
|
58
|
+
|
|
59
|
+
## Dependencies
|
|
60
|
+
|
|
61
|
+
- `click>=8.0.0`
|
|
62
|
+
- `rich>=13.0.0`
|
|
63
|
+
- `pydantic>=2.0.0`
|
|
64
|
+
- `httpx>=0.24.0`
|
|
65
|
+
- `requests>=2.31,<3.0`
|
|
66
|
+
|
|
67
|
+
## License
|
|
68
|
+
|
|
69
|
+
MIT — see [LICENSE](../../LICENSE)
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: deepctl-cmd-debug-network
|
|
3
|
-
Version: 0.1.8
|
|
4
|
-
Summary: Network debug subcommand for deepctl
|
|
5
|
-
Author-email: Deepgram <devrel@deepgram.com>
|
|
6
|
-
Maintainer-email: Deepgram <devrel@deepgram.com>
|
|
7
|
-
License-Expression: MIT
|
|
8
|
-
Keywords: deepgram,cli,debug,network,diagnostics
|
|
9
|
-
Classifier: Development Status :: 3 - Alpha
|
|
10
|
-
Classifier: Intended Audience :: Developers
|
|
11
|
-
Classifier: Programming Language :: Python :: 3
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
-
Requires-Python: >=3.10
|
|
16
|
-
Description-Content-Type: text/markdown
|
|
17
|
-
Requires-Dist: deepctl-core>=0.1.8
|
|
18
|
-
Requires-Dist: click>=8.0.0
|
|
19
|
-
Requires-Dist: rich>=13.0.0
|
|
20
|
-
Requires-Dist: pydantic>=2.0.0
|
|
21
|
-
Requires-Dist: httpx>=0.24.0
|
|
22
|
-
Requires-Dist: requests<3.0,>=2.31
|
|
23
|
-
|
|
24
|
-
# deepctl-cmd-debug-network
|
|
25
|
-
|
|
26
|
-
Network debug subcommand for the Deepgram CLI (deepctl). This package provides the `network` subcommand under the `debug` command group, allowing users to debug network issues or problems connecting to api.deepgram.com
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: deepctl-cmd-debug-network
|
|
3
|
-
Version: 0.1.8
|
|
4
|
-
Summary: Network debug subcommand for deepctl
|
|
5
|
-
Author-email: Deepgram <devrel@deepgram.com>
|
|
6
|
-
Maintainer-email: Deepgram <devrel@deepgram.com>
|
|
7
|
-
License-Expression: MIT
|
|
8
|
-
Keywords: deepgram,cli,debug,network,diagnostics
|
|
9
|
-
Classifier: Development Status :: 3 - Alpha
|
|
10
|
-
Classifier: Intended Audience :: Developers
|
|
11
|
-
Classifier: Programming Language :: Python :: 3
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
-
Requires-Python: >=3.10
|
|
16
|
-
Description-Content-Type: text/markdown
|
|
17
|
-
Requires-Dist: deepctl-core>=0.1.8
|
|
18
|
-
Requires-Dist: click>=8.0.0
|
|
19
|
-
Requires-Dist: rich>=13.0.0
|
|
20
|
-
Requires-Dist: pydantic>=2.0.0
|
|
21
|
-
Requires-Dist: httpx>=0.24.0
|
|
22
|
-
Requires-Dist: requests<3.0,>=2.31
|
|
23
|
-
|
|
24
|
-
# deepctl-cmd-debug-network
|
|
25
|
-
|
|
26
|
-
Network debug subcommand for the Deepgram CLI (deepctl). This package provides the `network` subcommand under the `debug` command group, allowing users to debug network issues or problems connecting to api.deepgram.com
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|