eeroctl 1.1.1__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.
Files changed (70) hide show
  1. eero_cli/__init__.py +11 -0
  2. eero_cli/commands/__init__.py +32 -0
  3. eero_cli/commands/activity.py +215 -0
  4. eero_cli/commands/auth.py +467 -0
  5. eero_cli/commands/completion.py +142 -0
  6. eero_cli/commands/device.py +472 -0
  7. eero_cli/commands/eero/__init__.py +12 -0
  8. eero_cli/commands/eero/base.py +214 -0
  9. eero_cli/commands/eero/led.py +154 -0
  10. eero_cli/commands/eero/nightlight.py +235 -0
  11. eero_cli/commands/eero/updates.py +82 -0
  12. eero_cli/commands/network/__init__.py +18 -0
  13. eero_cli/commands/network/advanced.py +191 -0
  14. eero_cli/commands/network/backup.py +162 -0
  15. eero_cli/commands/network/base.py +321 -0
  16. eero_cli/commands/network/dhcp.py +118 -0
  17. eero_cli/commands/network/dns.py +197 -0
  18. eero_cli/commands/network/forwards.py +115 -0
  19. eero_cli/commands/network/guest.py +162 -0
  20. eero_cli/commands/network/security.py +162 -0
  21. eero_cli/commands/network/speedtest.py +99 -0
  22. eero_cli/commands/network/sqm.py +194 -0
  23. eero_cli/commands/profile.py +636 -0
  24. eero_cli/commands/troubleshoot.py +293 -0
  25. eero_cli/context.py +254 -0
  26. eero_cli/errors.py +156 -0
  27. eero_cli/exit_codes.py +68 -0
  28. eero_cli/formatting.py +1130 -0
  29. eero_cli/main.py +148 -0
  30. eero_cli/output.py +739 -0
  31. eero_cli/safety.py +259 -0
  32. eero_cli/utils.py +181 -0
  33. eeroctl/__init__.py +11 -0
  34. eeroctl/commands/__init__.py +32 -0
  35. eeroctl/commands/activity.py +215 -0
  36. eeroctl/commands/auth.py +467 -0
  37. eeroctl/commands/completion.py +142 -0
  38. eeroctl/commands/device.py +472 -0
  39. eeroctl/commands/eero/__init__.py +12 -0
  40. eeroctl/commands/eero/base.py +214 -0
  41. eeroctl/commands/eero/led.py +154 -0
  42. eeroctl/commands/eero/nightlight.py +235 -0
  43. eeroctl/commands/eero/updates.py +82 -0
  44. eeroctl/commands/network/__init__.py +18 -0
  45. eeroctl/commands/network/advanced.py +191 -0
  46. eeroctl/commands/network/backup.py +162 -0
  47. eeroctl/commands/network/base.py +321 -0
  48. eeroctl/commands/network/dhcp.py +118 -0
  49. eeroctl/commands/network/dns.py +197 -0
  50. eeroctl/commands/network/forwards.py +115 -0
  51. eeroctl/commands/network/guest.py +162 -0
  52. eeroctl/commands/network/security.py +162 -0
  53. eeroctl/commands/network/speedtest.py +99 -0
  54. eeroctl/commands/network/sqm.py +194 -0
  55. eeroctl/commands/profile.py +636 -0
  56. eeroctl/commands/troubleshoot.py +293 -0
  57. eeroctl/context.py +254 -0
  58. eeroctl/errors.py +156 -0
  59. eeroctl/exit_codes.py +68 -0
  60. eeroctl/formatting.py +1130 -0
  61. eeroctl/main.py +148 -0
  62. eeroctl/output.py +739 -0
  63. eeroctl/safety.py +259 -0
  64. eeroctl/utils.py +181 -0
  65. eeroctl-1.1.1.dist-info/METADATA +113 -0
  66. eeroctl-1.1.1.dist-info/RECORD +70 -0
  67. eeroctl-1.1.1.dist-info/WHEEL +5 -0
  68. eeroctl-1.1.1.dist-info/entry_points.txt +2 -0
  69. eeroctl-1.1.1.dist-info/licenses/LICENSE +21 -0
  70. eeroctl-1.1.1.dist-info/top_level.txt +2 -0
eero_cli/__init__.py ADDED
@@ -0,0 +1,11 @@
1
+ """Command-line interface for Eero client.
2
+
3
+ This package provides the CLI for managing Eero networks.
4
+
5
+ Entry point: eero_cli.main:cli
6
+ """
7
+
8
+ from .main import cli, main
9
+
10
+ __version__ = "1.2.2"
11
+ __all__ = ["cli", "main", "__version__"]
@@ -0,0 +1,32 @@
1
+ """New command structure for the Eero CLI.
2
+
3
+ This package contains the new noun-first command tree:
4
+ - auth: Authentication management
5
+ - network: Network configuration and settings
6
+ - eero: Mesh node management
7
+ - device: Connected device management
8
+ - profile: Profile/parental controls management
9
+ - activity: Network activity data (Eero Plus)
10
+ - troubleshoot: Diagnostics and troubleshooting
11
+ - completion: Shell completion
12
+ """
13
+
14
+ from .activity import activity_group
15
+ from .auth import auth_group
16
+ from .completion import completion_group
17
+ from .device import device_group
18
+ from .eero import eero_group
19
+ from .network import network_group
20
+ from .profile import profile_group
21
+ from .troubleshoot import troubleshoot_group
22
+
23
+ __all__ = [
24
+ "auth_group",
25
+ "network_group",
26
+ "eero_group",
27
+ "device_group",
28
+ "profile_group",
29
+ "activity_group",
30
+ "troubleshoot_group",
31
+ "completion_group",
32
+ ]
@@ -0,0 +1,215 @@
1
+ """Activity commands for the Eero CLI (Eero Plus feature).
2
+
3
+ Commands:
4
+ - eero activity summary: Network activity summary
5
+ - eero activity clients: Per-client activity
6
+ - eero activity history: Historical activity
7
+ - eero activity categories: Activity by category
8
+ """
9
+
10
+ import sys
11
+
12
+ import click
13
+ from eero import EeroClient
14
+ from rich.panel import Panel
15
+ from rich.table import Table
16
+
17
+ from ..context import ensure_cli_context, get_cli_context
18
+ from ..errors import is_premium_error
19
+ from ..exit_codes import ExitCode
20
+ from ..utils import with_client
21
+
22
+
23
+ def _format_bytes(bytes_val: int) -> str:
24
+ """Format bytes into human-readable format."""
25
+ if bytes_val < 1024:
26
+ return f"{bytes_val} B"
27
+ elif bytes_val < 1024 * 1024:
28
+ return f"{bytes_val / 1024:.1f} KB"
29
+ elif bytes_val < 1024 * 1024 * 1024:
30
+ return f"{bytes_val / (1024 * 1024):.1f} MB"
31
+ else:
32
+ return f"{bytes_val / (1024 * 1024 * 1024):.2f} GB"
33
+
34
+
35
+ @click.group(name="activity")
36
+ @click.pass_context
37
+ def activity_group(ctx: click.Context) -> None:
38
+ """View network activity data (Eero Plus feature).
39
+
40
+ \b
41
+ Commands:
42
+ summary - Network activity summary
43
+ clients - Per-client activity
44
+ history - Historical activity
45
+ categories - Activity by category
46
+
47
+ \b
48
+ Note: Requires an active Eero Plus subscription.
49
+
50
+ \b
51
+ Examples:
52
+ eero activity summary
53
+ eero activity clients
54
+ eero activity history --period week
55
+ """
56
+ ensure_cli_context(ctx)
57
+
58
+
59
+ @activity_group.command(name="summary")
60
+ @click.pass_context
61
+ @with_client
62
+ async def activity_summary(ctx: click.Context, client: EeroClient) -> None:
63
+ """Show network activity summary."""
64
+ cli_ctx = get_cli_context(ctx)
65
+ console = cli_ctx.console
66
+
67
+ with cli_ctx.status("Getting network activity..."):
68
+ try:
69
+ activity_data = await client.get_activity(cli_ctx.network_id)
70
+ except Exception as e:
71
+ if is_premium_error(e):
72
+ console.print("[yellow]This feature requires Eero Plus subscription[/yellow]")
73
+ sys.exit(ExitCode.PREMIUM_REQUIRED)
74
+ raise
75
+
76
+ if cli_ctx.is_structured_output():
77
+ cli_ctx.render_structured(activity_data, "eero.activity.summary/v1")
78
+ else:
79
+ upload = activity_data.get("upload_bytes", 0)
80
+ download = activity_data.get("download_bytes", 0)
81
+ total = upload + download
82
+
83
+ content = (
84
+ f"[bold cyan]Download:[/bold cyan] {_format_bytes(download)}\n"
85
+ f"[bold cyan]Upload:[/bold cyan] {_format_bytes(upload)}\n"
86
+ f"[bold cyan]Total:[/bold cyan] {_format_bytes(total)}"
87
+ )
88
+ console.print(Panel(content, title="Network Activity Summary", border_style="blue"))
89
+
90
+
91
+ @activity_group.command(name="clients")
92
+ @click.pass_context
93
+ @with_client
94
+ async def activity_clients(ctx: click.Context, client: EeroClient) -> None:
95
+ """Show per-client activity data."""
96
+ cli_ctx = get_cli_context(ctx)
97
+ console = cli_ctx.console
98
+
99
+ with cli_ctx.status("Getting client activity..."):
100
+ try:
101
+ clients_data = await client.get_activity_clients(cli_ctx.network_id)
102
+ except Exception as e:
103
+ if is_premium_error(e):
104
+ console.print("[yellow]This feature requires Eero Plus subscription[/yellow]")
105
+ sys.exit(ExitCode.PREMIUM_REQUIRED)
106
+ raise
107
+
108
+ if cli_ctx.is_structured_output():
109
+ cli_ctx.render_structured(clients_data, "eero.activity.clients/v1")
110
+ else:
111
+ if not clients_data:
112
+ console.print("[yellow]No client activity data available[/yellow]")
113
+ return
114
+
115
+ table = Table(title="Client Activity")
116
+ table.add_column("Device", style="cyan")
117
+ table.add_column("Download", justify="right")
118
+ table.add_column("Upload", justify="right")
119
+ table.add_column("Total", justify="right")
120
+
121
+ for client_info in clients_data:
122
+ name = (
123
+ client_info.get("display_name")
124
+ or client_info.get("hostname")
125
+ or client_info.get("mac", "Unknown")
126
+ )
127
+ download = client_info.get("download_bytes", 0)
128
+ upload = client_info.get("upload_bytes", 0)
129
+ total = download + upload
130
+
131
+ table.add_row(
132
+ name, _format_bytes(download), _format_bytes(upload), _format_bytes(total)
133
+ )
134
+
135
+ console.print(table)
136
+
137
+
138
+ @activity_group.command(name="history")
139
+ @click.option(
140
+ "--period",
141
+ type=click.Choice(["hour", "day", "week", "month"]),
142
+ default="day",
143
+ help="Time period (default: day)",
144
+ )
145
+ @click.pass_context
146
+ @with_client
147
+ async def activity_history(ctx: click.Context, client: EeroClient, period: str) -> None:
148
+ """Show historical activity data.
149
+
150
+ \b
151
+ Options:
152
+ --period Time period: hour, day, week, month
153
+ """
154
+ cli_ctx = get_cli_context(ctx)
155
+ console = cli_ctx.console
156
+
157
+ with cli_ctx.status(f"Getting activity history ({period})..."):
158
+ try:
159
+ history_data = await client.get_activity_history(cli_ctx.network_id, period)
160
+ except Exception as e:
161
+ if is_premium_error(e):
162
+ console.print("[yellow]This feature requires Eero Plus subscription[/yellow]")
163
+ sys.exit(ExitCode.PREMIUM_REQUIRED)
164
+ raise
165
+
166
+ if cli_ctx.is_structured_output():
167
+ cli_ctx.render_structured(history_data, "eero.activity.history/v1")
168
+ else:
169
+ total_download = history_data.get("total_download_bytes", 0)
170
+ total_upload = history_data.get("total_upload_bytes", 0)
171
+ data_points = history_data.get("data_points", [])
172
+
173
+ content = (
174
+ f"[bold]Period:[/bold] {period}\n"
175
+ f"[bold cyan]Total Download:[/bold cyan] {_format_bytes(total_download)}\n"
176
+ f"[bold cyan]Total Upload:[/bold cyan] {_format_bytes(total_upload)}\n"
177
+ f"[bold]Data Points:[/bold] {len(data_points)}"
178
+ )
179
+ console.print(Panel(content, title=f"Activity History ({period})", border_style="blue"))
180
+
181
+
182
+ @activity_group.command(name="categories")
183
+ @click.pass_context
184
+ @with_client
185
+ async def activity_categories(ctx: click.Context, client: EeroClient) -> None:
186
+ """Show activity grouped by category."""
187
+ cli_ctx = get_cli_context(ctx)
188
+ console = cli_ctx.console
189
+
190
+ with cli_ctx.status("Getting activity categories..."):
191
+ try:
192
+ categories_data = await client.get_activity_categories(cli_ctx.network_id)
193
+ except Exception as e:
194
+ if is_premium_error(e):
195
+ console.print("[yellow]This feature requires Eero Plus subscription[/yellow]")
196
+ sys.exit(ExitCode.PREMIUM_REQUIRED)
197
+ raise
198
+
199
+ if cli_ctx.is_structured_output():
200
+ cli_ctx.render_structured(categories_data, "eero.activity.categories/v1")
201
+ else:
202
+ if not categories_data:
203
+ console.print("[yellow]No category data available[/yellow]")
204
+ return
205
+
206
+ table = Table(title="Activity by Category")
207
+ table.add_column("Category", style="cyan")
208
+ table.add_column("Usage", justify="right")
209
+
210
+ for category in categories_data:
211
+ name = category.get("name", "Unknown")
212
+ usage = category.get("bytes", 0)
213
+ table.add_row(name, _format_bytes(usage))
214
+
215
+ console.print(table)