impreza-cli 0.3.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.
Files changed (62) hide show
  1. impreza_cli-0.3.0/PKG-INFO +296 -0
  2. impreza_cli-0.3.0/README.md +255 -0
  3. impreza_cli-0.3.0/impreza_cli/__init__.py +14 -0
  4. impreza_cli-0.3.0/impreza_cli/commands/__init__.py +7 -0
  5. impreza_cli-0.3.0/impreza_cli/commands/_helpers.py +128 -0
  6. impreza_cli-0.3.0/impreza_cli/commands/account.py +576 -0
  7. impreza_cli-0.3.0/impreza_cli/commands/catalog.py +270 -0
  8. impreza_cli-0.3.0/impreza_cli/commands/context.py +232 -0
  9. impreza_cli-0.3.0/impreza_cli/commands/doctor.py +427 -0
  10. impreza_cli-0.3.0/impreza_cli/commands/domain.py +858 -0
  11. impreza_cli-0.3.0/impreza_cli/commands/invoice.py +198 -0
  12. impreza_cli-0.3.0/impreza_cli/commands/key.py +104 -0
  13. impreza_cli-0.3.0/impreza_cli/commands/orders.py +478 -0
  14. impreza_cli-0.3.0/impreza_cli/commands/services.py +100 -0
  15. impreza_cli-0.3.0/impreza_cli/commands/vps.py +812 -0
  16. impreza_cli-0.3.0/impreza_cli/commands/vps_cloud.py +865 -0
  17. impreza_cli-0.3.0/impreza_cli/commands/vps_proxmox.py +727 -0
  18. impreza_cli-0.3.0/impreza_cli/commands/webhooks.py +483 -0
  19. impreza_cli-0.3.0/impreza_cli/config.py +405 -0
  20. impreza_cli-0.3.0/impreza_cli/main.py +100 -0
  21. impreza_cli-0.3.0/impreza_cli/output.py +207 -0
  22. impreza_cli-0.3.0/impreza_cli/sdk.py +97 -0
  23. impreza_cli-0.3.0/impreza_cli/state.py +94 -0
  24. impreza_cli-0.3.0/impreza_cli.egg-info/PKG-INFO +296 -0
  25. impreza_cli-0.3.0/impreza_cli.egg-info/SOURCES.txt +60 -0
  26. impreza_cli-0.3.0/impreza_cli.egg-info/dependency_links.txt +1 -0
  27. impreza_cli-0.3.0/impreza_cli.egg-info/entry_points.txt +2 -0
  28. impreza_cli-0.3.0/impreza_cli.egg-info/requires.txt +20 -0
  29. impreza_cli-0.3.0/impreza_cli.egg-info/top_level.txt +1 -0
  30. impreza_cli-0.3.0/pyproject.toml +114 -0
  31. impreza_cli-0.3.0/setup.cfg +4 -0
  32. impreza_cli-0.3.0/tests/.gitkeep +0 -0
  33. impreza_cli-0.3.0/tests/__init__.py +0 -0
  34. impreza_cli-0.3.0/tests/conftest.py +24 -0
  35. impreza_cli-0.3.0/tests/test_account_commands.py +336 -0
  36. impreza_cli-0.3.0/tests/test_account_topup_commands.py +541 -0
  37. impreza_cli-0.3.0/tests/test_catalog_commands.py +343 -0
  38. impreza_cli-0.3.0/tests/test_config.py +252 -0
  39. impreza_cli-0.3.0/tests/test_context_commands.py +324 -0
  40. impreza_cli-0.3.0/tests/test_doctor_commands.py +409 -0
  41. impreza_cli-0.3.0/tests/test_domain_commands.py +848 -0
  42. impreza_cli-0.3.0/tests/test_invoice_commands.py +242 -0
  43. impreza_cli-0.3.0/tests/test_key_commands.py +168 -0
  44. impreza_cli-0.3.0/tests/test_orders_commands.py +406 -0
  45. impreza_cli-0.3.0/tests/test_phase_2_2_smoke.py +138 -0
  46. impreza_cli-0.3.0/tests/test_phase_2_3_smoke.py +117 -0
  47. impreza_cli-0.3.0/tests/test_phase_2_4_smoke.py +208 -0
  48. impreza_cli-0.3.0/tests/test_phase_2_5_smoke.py +140 -0
  49. impreza_cli-0.3.0/tests/test_phase_2_6_smoke.py +146 -0
  50. impreza_cli-0.3.0/tests/test_phase_3_1_smoke.py +225 -0
  51. impreza_cli-0.3.0/tests/test_phase_3_2_smoke.py +222 -0
  52. impreza_cli-0.3.0/tests/test_phase_3_3_smoke.py +179 -0
  53. impreza_cli-0.3.0/tests/test_phase_3_4_smoke.py +223 -0
  54. impreza_cli-0.3.0/tests/test_phase_3_5_smoke.py +233 -0
  55. impreza_cli-0.3.0/tests/test_phase_3_6_smoke.py +112 -0
  56. impreza_cli-0.3.0/tests/test_phase_3_7_smoke.py +183 -0
  57. impreza_cli-0.3.0/tests/test_services_commands.py +145 -0
  58. impreza_cli-0.3.0/tests/test_vps_cloud_commands.py +549 -0
  59. impreza_cli-0.3.0/tests/test_vps_commands.py +949 -0
  60. impreza_cli-0.3.0/tests/test_vps_proxmox_commands.py +634 -0
  61. impreza_cli-0.3.0/tests/test_webhooks_commands.py +449 -0
  62. impreza_cli-0.3.0/tests/test_yaml_output.py +340 -0
@@ -0,0 +1,296 @@
1
+ Metadata-Version: 2.4
2
+ Name: impreza-cli
3
+ Version: 0.3.0
4
+ Summary: Official command-line interface for the Impreza Host public REST API
5
+ Author-email: Impreza Host <support@imprezahost.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://imprezahost.com
8
+ Project-URL: Documentation, https://docs.imprezahost.com
9
+ Project-URL: Repository, https://github.com/imprezahost/impreza-devkit
10
+ Project-URL: Changelog, https://github.com/imprezahost/impreza-devkit/blob/master/CHANGELOG.md
11
+ Keywords: impreza,hosting,cli,offshore,crypto
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: System Administrators
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Topic :: Internet :: WWW/HTTP
23
+ Classifier: Topic :: Utilities
24
+ Requires-Python: >=3.10
25
+ Description-Content-Type: text/markdown
26
+ Requires-Dist: impreza-sdk
27
+ Requires-Dist: typer>=0.12
28
+ Requires-Dist: rich>=13.7
29
+ Requires-Dist: tomli>=2.0; python_version < "3.11"
30
+ Requires-Dist: tomli-w>=1.0
31
+ Provides-Extra: test
32
+ Requires-Dist: pytest>=8.0; extra == "test"
33
+ Requires-Dist: pytest-cov>=4.1; extra == "test"
34
+ Requires-Dist: pyyaml>=6.0; extra == "test"
35
+ Requires-Dist: types-PyYAML>=6.0; extra == "test"
36
+ Provides-Extra: dev
37
+ Requires-Dist: ruff>=0.5; extra == "dev"
38
+ Requires-Dist: mypy>=1.8; extra == "dev"
39
+ Provides-Extra: yaml
40
+ Requires-Dist: pyyaml>=6.0; extra == "yaml"
41
+
42
+ # `impreza-cli` — Official CLI for Impreza Host
43
+
44
+ Command-line interface for the Impreza Host public REST API.
45
+ Built on top of [`impreza-sdk`](../sdk-python/README.md) — same
46
+ auth model, same Tor support, same retry behaviour, plus
47
+ multi-context configuration and Rich-rendered tables for human-
48
+ friendly output.
49
+
50
+ ```bash
51
+ pip install impreza-cli
52
+ ```
53
+
54
+ Requires Python 3.10+. See [`../CHANGELOG.md`](../CHANGELOG.md) for
55
+ release history.
56
+
57
+ ## Quickstart
58
+
59
+ ```bash
60
+ # 1. Add a context with your API credentials. Generate keys in
61
+ # Impreza Account → API Keys; whitelist the calling
62
+ # machine's IP at the same screen.
63
+ $ impreza context create personal --key imp_... --secret ...
64
+ Context 'personal' created and set as default.
65
+
66
+ # 2. Confirm everything works. impreza doctor runs five sequenced
67
+ # health checks (config, API reachable, key status, IP
68
+ # whitelist, account profile) and exits 0 only if all pass.
69
+ $ impreza doctor
70
+
71
+ impreza doctor
72
+ ----------------------------------------
73
+ [OK] active-context: Default context
74
+ [OK] api-reachable: GET /account/api-keys/self OK (142ms)
75
+ key prefix='imp_a1b2c3d4', label='devkit'
76
+ [OK] key-status: status='active'
77
+ [OK] ip-whitelist: request_ip 200.1.2.3 matches entry ('home')
78
+ [OK] account-profile: Jane Doe <jane@example.com>, balance 5.00 USD
79
+ registered 2024-01-15
80
+ ----------------------------------------
81
+ All checks passed. 5/5.
82
+
83
+ # 3. Read commands span every resource group:
84
+ $ impreza account info # profile + balance
85
+ $ impreza vps list # across both backends
86
+ $ impreza domain check example.com mydomain.io
87
+ $ impreza catalog products --group "VPS"
88
+
89
+ # 4. Pipe into jq for scripting (every read verb supports --output
90
+ # json | yaml):
91
+ $ impreza invoice list --output json \
92
+ | jq '[.[] | select(.status == "Unpaid")] | length'
93
+
94
+ # 5. Write verbs are gated by confirm_or_exit so you don't lose
95
+ # data accidentally; pass --yes / -y to skip prompts in scripts:
96
+ $ impreza vps reboot 17988
97
+ $ impreza vps proxmox snapshots create 17988 pre-update
98
+ $ impreza domain dns add example.com --type A --name www --value 1.2.3.4
99
+
100
+ # 6. Crypto top-up. --browser opens the BTCPay invoice URL
101
+ # automatically; --wait polls until the gateway confirms
102
+ # (default 2h timeout matches server-side invoice expiry).
103
+ $ impreza account topup --amount 50 --method xmr --browser --wait
104
+ ```
105
+
106
+ ## Authentication
107
+
108
+ Two ways to authenticate. The CLI tries them in order:
109
+
110
+ 1. **Context** (recommended) — `impreza context create <name>` stores
111
+ credentials in a config file; commands read them automatically.
112
+ Per-invocation override via `impreza --context other <command>`.
113
+
114
+ 2. **Environment variables** — `IMPREZA_API_KEY` + `IMPREZA_API_SECRET`.
115
+ Useful in CI, but contexts are preferred for local work.
116
+
117
+ The config file lives at:
118
+
119
+ | OS | Path |
120
+ |---|---|
121
+ | Linux | `$XDG_CONFIG_HOME/impreza/config.toml` (default `~/.config/impreza/config.toml`) |
122
+ | macOS | `~/Library/Application Support/impreza/config.toml` |
123
+ | Windows | `%APPDATA%\impreza\config.toml` |
124
+
125
+ Override with `IMPREZA_CONFIG=/path/to/config.toml` for testing or
126
+ non-standard layouts.
127
+
128
+ On POSIX, the config file is `chmod 0o600` after every write so only
129
+ the owner can read the credentials. Windows ACLs are left to the OS
130
+ default.
131
+
132
+ ## Commands
133
+
134
+ The CLI groups commands by resource. Run `impreza <group> --help`
135
+ to see the full subcommand list, or `impreza <group> <command>
136
+ --help` for option-level detail.
137
+
138
+ | Group | Verbs | Notes |
139
+ |---|---|---|
140
+ | `context` | `create / use / list / current / delete` | Local credential management — never hits the network |
141
+ | `doctor` | (single command) | Health check — config + API reachable + key status + IP whitelist + account profile |
142
+ | `account` | `info / balance / services / topup / topup-status` | Profile + balance + services + crypto top-up |
143
+ | `catalog` | `products / product / product-groups / tlds` | Pre-purchase discovery |
144
+ | `domain` | `show / check / pricing / register / transfer / set-nameservers / lock / unlock / id-protection / raa-verify / gdpr-auth / transfer-approval` + `domain dns list / add / update / delete / activate` | Domain registrations + full DNS CRUD |
145
+ | `vps` | `list / show / status / start / stop / reboot / shutdown / set-hostname / set-password / reinstall / migrate / cancel` + `vps proxmox snapshots / backups / backup-schedules / network` + `vps cloud images / rescue / iso / rdns / ssh-keys / vnc / vnc-password / resize / boot-order / ipv6` | Cross-backend (Proxmox + Cloud) VPS with smart dispatch |
146
+ | `order` | `list / show / create / upgrade` | Submit / browse product orders |
147
+ | `service` | `cancel` | Submit cancellation request (any service) |
148
+ | `webhook` | `list / show / create / update / delete / rotate-secret / deliveries / event-types` | Webhook subscription management + delivery history |
149
+ | `invoice` | `list / show` | Invoices with line items + transactions |
150
+ | `key` | `whoami` | Active API key identity + IP whitelist |
151
+
152
+ **Conventions:**
153
+
154
+ - Destructive verbs prompt for confirmation; pass `--yes` / `-y`
155
+ to skip the prompt in scripts.
156
+ - Operation-returning verbs (`vps reinstall`, `vps migrate`,
157
+ `vps proxmox snapshots rollback`, `vps proxmox backups
158
+ create/restore`) accept `--wait` to block on the Proxmox queue,
159
+ with `--timeout` (default 600 s for fast ops, 1800 s for the
160
+ slower restores).
161
+ - Cost-incurring verbs (`domain register/transfer/id-protection`,
162
+ `order create/upgrade`, `account topup`) call out the
163
+ balance impact in the confirmation prompt; an
164
+ `InsufficientCredit` 402 surfaces with a hint pointing at
165
+ `impreza account topup`.
166
+ - Verbs that mutate a resource emit a green success line on
167
+ stdout; queued / reboot-required state changes emit a cyan
168
+ info line. Errors are red on stderr.
169
+
170
+ **Service termination policy:** `service cancel` / `vps cancel`
171
+ submit an `AddCancelRequest` — staff approves the actual
172
+ termination. There is no direct customer path to terminate a
173
+ service or remove a service suspension (suspension is
174
+ billing-state and is removed automatically when the overdue
175
+ invoice is paid, or manually by staff after an abuse hold is
176
+ resolved).
177
+
178
+ ## Output formats
179
+
180
+ Every command supports `--output table|json|yaml` (short form `-o`).
181
+
182
+ | Format | Default | Best for |
183
+ |---|---|---|
184
+ | `table` | yes | human reading at the terminal |
185
+ | `json` | | piping into `jq`, automation, scripting |
186
+ | `yaml` | | human-editable config snapshots, CI/CD pipelines |
187
+
188
+ YAML output requires the optional `pyyaml` dependency:
189
+
190
+ ```bash
191
+ pip install impreza-cli[yaml]
192
+ ```
193
+
194
+ The CLI raises a clear `RuntimeError` pointing at the install hint
195
+ if you select `--output yaml` without it.
196
+
197
+ The flag works at both the global level and per-command:
198
+
199
+ ```bash
200
+ # Global default for the invocation
201
+ impreza --output json account info
202
+
203
+ # Per-command override (wins over global)
204
+ impreza --output yaml account info --output table
205
+ ```
206
+
207
+ ## Tab completion
208
+
209
+ Typer ships completion for `bash`, `zsh`, `fish`, and PowerShell
210
+ out of the box:
211
+
212
+ ```bash
213
+ # Install for the current shell (auto-detected)
214
+ impreza --install-completion
215
+
216
+ # Or explicitly
217
+ impreza --install-completion bash # / zsh / fish / powershell
218
+
219
+ # Inspect the script before installing
220
+ impreza --show-completion bash
221
+ ```
222
+
223
+ After installing, restart the shell (or `source ~/.bashrc` /
224
+ equivalent) and `impreza <TAB>` should suggest resource groups,
225
+ `impreza account <TAB>` should suggest verbs, and so on.
226
+
227
+ ## Tor
228
+
229
+ Inherited from the SDK. Three knobs:
230
+
231
+ ```bash
232
+ # Per-context override at create time
233
+ impreza context create offshore \
234
+ --key imp_... --secret ... \
235
+ # No --proxy flag yet; for now, set IMPREZA_USE_TOR before invoking
236
+
237
+ # Env var, picked up by the SDK transparently
238
+ IMPREZA_USE_TOR=1 impreza account info
239
+
240
+ # Programmatic via the SDK (Python users skip the CLI for this)
241
+ ```
242
+
243
+ The SDK's `auto_tor=True` path (probe Tor, fall back to clearnet)
244
+ isn't surfaced through the CLI yet — coming in a future release
245
+ alongside the `--via-tor` shortcut.
246
+
247
+ ## Error handling
248
+
249
+ The CLI maps SDK exceptions to friendly stderr messages and a
250
+ non-zero exit code, matching the format `ImprezaError.__str__`
251
+ produces:
252
+
253
+ ```
254
+ Error: Invalid API credentials. (code=UNAUTHORIZED) [request_id=req_abc]
255
+ ```
256
+
257
+ Tracebacks never leak from expected failures (auth errors, missing
258
+ contexts, 404s, 429s, etc.). Bugs in the CLI itself still raise so
259
+ the traceback isn't swallowed — that's intentional.
260
+
261
+ ## Development
262
+
263
+ ```bash
264
+ git clone https://github.com/imprezahost/impreza-devkit.git
265
+ cd impreza-devkit/cli-python
266
+
267
+ python -m venv .venv
268
+ # Linux/macOS: source .venv/bin/activate
269
+ # Windows PowerShell: .venv\Scripts\Activate.ps1
270
+
271
+ # Install editable + test/dev/yaml extras + the SDK as a path dep
272
+ pip install -e ../sdk-python -e ".[test,dev,yaml]"
273
+
274
+ pytest # unit + Typer-runner E2E
275
+ ruff check
276
+ mypy --strict impreza_cli
277
+ ```
278
+
279
+ To run the live integration smokes (skipped silently without creds):
280
+
281
+ ```bash
282
+ export IMPREZA_API_KEY="imp_..."
283
+ export IMPREZA_API_SECRET="..."
284
+ # Optional, for `impreza domain show / dns list`:
285
+ export IMPREZA_TEST_DOMAIN="<a domain on your account>"
286
+
287
+ pytest -v -s tests/
288
+ ```
289
+
290
+ The smokes exercise the same surface as the unit tests against the
291
+ real API, so they catch contract drift between the CLI and the
292
+ server.
293
+
294
+ ## License
295
+
296
+ MIT. See [`../LICENSE`](../LICENSE) at the repository root.
@@ -0,0 +1,255 @@
1
+ # `impreza-cli` — Official CLI for Impreza Host
2
+
3
+ Command-line interface for the Impreza Host public REST API.
4
+ Built on top of [`impreza-sdk`](../sdk-python/README.md) — same
5
+ auth model, same Tor support, same retry behaviour, plus
6
+ multi-context configuration and Rich-rendered tables for human-
7
+ friendly output.
8
+
9
+ ```bash
10
+ pip install impreza-cli
11
+ ```
12
+
13
+ Requires Python 3.10+. See [`../CHANGELOG.md`](../CHANGELOG.md) for
14
+ release history.
15
+
16
+ ## Quickstart
17
+
18
+ ```bash
19
+ # 1. Add a context with your API credentials. Generate keys in
20
+ # Impreza Account → API Keys; whitelist the calling
21
+ # machine's IP at the same screen.
22
+ $ impreza context create personal --key imp_... --secret ...
23
+ Context 'personal' created and set as default.
24
+
25
+ # 2. Confirm everything works. impreza doctor runs five sequenced
26
+ # health checks (config, API reachable, key status, IP
27
+ # whitelist, account profile) and exits 0 only if all pass.
28
+ $ impreza doctor
29
+
30
+ impreza doctor
31
+ ----------------------------------------
32
+ [OK] active-context: Default context
33
+ [OK] api-reachable: GET /account/api-keys/self OK (142ms)
34
+ key prefix='imp_a1b2c3d4', label='devkit'
35
+ [OK] key-status: status='active'
36
+ [OK] ip-whitelist: request_ip 200.1.2.3 matches entry ('home')
37
+ [OK] account-profile: Jane Doe <jane@example.com>, balance 5.00 USD
38
+ registered 2024-01-15
39
+ ----------------------------------------
40
+ All checks passed. 5/5.
41
+
42
+ # 3. Read commands span every resource group:
43
+ $ impreza account info # profile + balance
44
+ $ impreza vps list # across both backends
45
+ $ impreza domain check example.com mydomain.io
46
+ $ impreza catalog products --group "VPS"
47
+
48
+ # 4. Pipe into jq for scripting (every read verb supports --output
49
+ # json | yaml):
50
+ $ impreza invoice list --output json \
51
+ | jq '[.[] | select(.status == "Unpaid")] | length'
52
+
53
+ # 5. Write verbs are gated by confirm_or_exit so you don't lose
54
+ # data accidentally; pass --yes / -y to skip prompts in scripts:
55
+ $ impreza vps reboot 17988
56
+ $ impreza vps proxmox snapshots create 17988 pre-update
57
+ $ impreza domain dns add example.com --type A --name www --value 1.2.3.4
58
+
59
+ # 6. Crypto top-up. --browser opens the BTCPay invoice URL
60
+ # automatically; --wait polls until the gateway confirms
61
+ # (default 2h timeout matches server-side invoice expiry).
62
+ $ impreza account topup --amount 50 --method xmr --browser --wait
63
+ ```
64
+
65
+ ## Authentication
66
+
67
+ Two ways to authenticate. The CLI tries them in order:
68
+
69
+ 1. **Context** (recommended) — `impreza context create <name>` stores
70
+ credentials in a config file; commands read them automatically.
71
+ Per-invocation override via `impreza --context other <command>`.
72
+
73
+ 2. **Environment variables** — `IMPREZA_API_KEY` + `IMPREZA_API_SECRET`.
74
+ Useful in CI, but contexts are preferred for local work.
75
+
76
+ The config file lives at:
77
+
78
+ | OS | Path |
79
+ |---|---|
80
+ | Linux | `$XDG_CONFIG_HOME/impreza/config.toml` (default `~/.config/impreza/config.toml`) |
81
+ | macOS | `~/Library/Application Support/impreza/config.toml` |
82
+ | Windows | `%APPDATA%\impreza\config.toml` |
83
+
84
+ Override with `IMPREZA_CONFIG=/path/to/config.toml` for testing or
85
+ non-standard layouts.
86
+
87
+ On POSIX, the config file is `chmod 0o600` after every write so only
88
+ the owner can read the credentials. Windows ACLs are left to the OS
89
+ default.
90
+
91
+ ## Commands
92
+
93
+ The CLI groups commands by resource. Run `impreza <group> --help`
94
+ to see the full subcommand list, or `impreza <group> <command>
95
+ --help` for option-level detail.
96
+
97
+ | Group | Verbs | Notes |
98
+ |---|---|---|
99
+ | `context` | `create / use / list / current / delete` | Local credential management — never hits the network |
100
+ | `doctor` | (single command) | Health check — config + API reachable + key status + IP whitelist + account profile |
101
+ | `account` | `info / balance / services / topup / topup-status` | Profile + balance + services + crypto top-up |
102
+ | `catalog` | `products / product / product-groups / tlds` | Pre-purchase discovery |
103
+ | `domain` | `show / check / pricing / register / transfer / set-nameservers / lock / unlock / id-protection / raa-verify / gdpr-auth / transfer-approval` + `domain dns list / add / update / delete / activate` | Domain registrations + full DNS CRUD |
104
+ | `vps` | `list / show / status / start / stop / reboot / shutdown / set-hostname / set-password / reinstall / migrate / cancel` + `vps proxmox snapshots / backups / backup-schedules / network` + `vps cloud images / rescue / iso / rdns / ssh-keys / vnc / vnc-password / resize / boot-order / ipv6` | Cross-backend (Proxmox + Cloud) VPS with smart dispatch |
105
+ | `order` | `list / show / create / upgrade` | Submit / browse product orders |
106
+ | `service` | `cancel` | Submit cancellation request (any service) |
107
+ | `webhook` | `list / show / create / update / delete / rotate-secret / deliveries / event-types` | Webhook subscription management + delivery history |
108
+ | `invoice` | `list / show` | Invoices with line items + transactions |
109
+ | `key` | `whoami` | Active API key identity + IP whitelist |
110
+
111
+ **Conventions:**
112
+
113
+ - Destructive verbs prompt for confirmation; pass `--yes` / `-y`
114
+ to skip the prompt in scripts.
115
+ - Operation-returning verbs (`vps reinstall`, `vps migrate`,
116
+ `vps proxmox snapshots rollback`, `vps proxmox backups
117
+ create/restore`) accept `--wait` to block on the Proxmox queue,
118
+ with `--timeout` (default 600 s for fast ops, 1800 s for the
119
+ slower restores).
120
+ - Cost-incurring verbs (`domain register/transfer/id-protection`,
121
+ `order create/upgrade`, `account topup`) call out the
122
+ balance impact in the confirmation prompt; an
123
+ `InsufficientCredit` 402 surfaces with a hint pointing at
124
+ `impreza account topup`.
125
+ - Verbs that mutate a resource emit a green success line on
126
+ stdout; queued / reboot-required state changes emit a cyan
127
+ info line. Errors are red on stderr.
128
+
129
+ **Service termination policy:** `service cancel` / `vps cancel`
130
+ submit an `AddCancelRequest` — staff approves the actual
131
+ termination. There is no direct customer path to terminate a
132
+ service or remove a service suspension (suspension is
133
+ billing-state and is removed automatically when the overdue
134
+ invoice is paid, or manually by staff after an abuse hold is
135
+ resolved).
136
+
137
+ ## Output formats
138
+
139
+ Every command supports `--output table|json|yaml` (short form `-o`).
140
+
141
+ | Format | Default | Best for |
142
+ |---|---|---|
143
+ | `table` | yes | human reading at the terminal |
144
+ | `json` | | piping into `jq`, automation, scripting |
145
+ | `yaml` | | human-editable config snapshots, CI/CD pipelines |
146
+
147
+ YAML output requires the optional `pyyaml` dependency:
148
+
149
+ ```bash
150
+ pip install impreza-cli[yaml]
151
+ ```
152
+
153
+ The CLI raises a clear `RuntimeError` pointing at the install hint
154
+ if you select `--output yaml` without it.
155
+
156
+ The flag works at both the global level and per-command:
157
+
158
+ ```bash
159
+ # Global default for the invocation
160
+ impreza --output json account info
161
+
162
+ # Per-command override (wins over global)
163
+ impreza --output yaml account info --output table
164
+ ```
165
+
166
+ ## Tab completion
167
+
168
+ Typer ships completion for `bash`, `zsh`, `fish`, and PowerShell
169
+ out of the box:
170
+
171
+ ```bash
172
+ # Install for the current shell (auto-detected)
173
+ impreza --install-completion
174
+
175
+ # Or explicitly
176
+ impreza --install-completion bash # / zsh / fish / powershell
177
+
178
+ # Inspect the script before installing
179
+ impreza --show-completion bash
180
+ ```
181
+
182
+ After installing, restart the shell (or `source ~/.bashrc` /
183
+ equivalent) and `impreza <TAB>` should suggest resource groups,
184
+ `impreza account <TAB>` should suggest verbs, and so on.
185
+
186
+ ## Tor
187
+
188
+ Inherited from the SDK. Three knobs:
189
+
190
+ ```bash
191
+ # Per-context override at create time
192
+ impreza context create offshore \
193
+ --key imp_... --secret ... \
194
+ # No --proxy flag yet; for now, set IMPREZA_USE_TOR before invoking
195
+
196
+ # Env var, picked up by the SDK transparently
197
+ IMPREZA_USE_TOR=1 impreza account info
198
+
199
+ # Programmatic via the SDK (Python users skip the CLI for this)
200
+ ```
201
+
202
+ The SDK's `auto_tor=True` path (probe Tor, fall back to clearnet)
203
+ isn't surfaced through the CLI yet — coming in a future release
204
+ alongside the `--via-tor` shortcut.
205
+
206
+ ## Error handling
207
+
208
+ The CLI maps SDK exceptions to friendly stderr messages and a
209
+ non-zero exit code, matching the format `ImprezaError.__str__`
210
+ produces:
211
+
212
+ ```
213
+ Error: Invalid API credentials. (code=UNAUTHORIZED) [request_id=req_abc]
214
+ ```
215
+
216
+ Tracebacks never leak from expected failures (auth errors, missing
217
+ contexts, 404s, 429s, etc.). Bugs in the CLI itself still raise so
218
+ the traceback isn't swallowed — that's intentional.
219
+
220
+ ## Development
221
+
222
+ ```bash
223
+ git clone https://github.com/imprezahost/impreza-devkit.git
224
+ cd impreza-devkit/cli-python
225
+
226
+ python -m venv .venv
227
+ # Linux/macOS: source .venv/bin/activate
228
+ # Windows PowerShell: .venv\Scripts\Activate.ps1
229
+
230
+ # Install editable + test/dev/yaml extras + the SDK as a path dep
231
+ pip install -e ../sdk-python -e ".[test,dev,yaml]"
232
+
233
+ pytest # unit + Typer-runner E2E
234
+ ruff check
235
+ mypy --strict impreza_cli
236
+ ```
237
+
238
+ To run the live integration smokes (skipped silently without creds):
239
+
240
+ ```bash
241
+ export IMPREZA_API_KEY="imp_..."
242
+ export IMPREZA_API_SECRET="..."
243
+ # Optional, for `impreza domain show / dns list`:
244
+ export IMPREZA_TEST_DOMAIN="<a domain on your account>"
245
+
246
+ pytest -v -s tests/
247
+ ```
248
+
249
+ The smokes exercise the same surface as the unit tests against the
250
+ real API, so they catch contract drift between the CLI and the
251
+ server.
252
+
253
+ ## License
254
+
255
+ MIT. See [`../LICENSE`](../LICENSE) at the repository root.
@@ -0,0 +1,14 @@
1
+ """Impreza Host CLI — official command-line interface for the
2
+ Impreza Host public REST API.
3
+
4
+ Phase 2.1 ships the multi-context machinery (config file at
5
+ ``$XDG_CONFIG_HOME/impreza/config.toml`` on Linux/macOS,
6
+ ``%APPDATA%\\impreza\\config.toml`` on Windows) and the
7
+ ``impreza context`` subcommand surface. Subsequent fases (2.2+)
8
+ add the read-only resource commands on top.
9
+
10
+ Built on top of :mod:`impreza` (the SDK), so the network layer,
11
+ auth, retry, and error handling are inherited.
12
+ """
13
+
14
+ __version__ = "0.1.0a0"
@@ -0,0 +1,7 @@
1
+ """Subcommand modules — one per resource group.
2
+
3
+ Each module exposes an ``app`` (a ``typer.Typer`` instance) that
4
+ ``impreza_cli.main`` mounts under the right command name. Phase 2.1
5
+ ships :mod:`.context`. Subsequent fases add ``account``, ``catalog``,
6
+ ``domain``, ``vps``, ``invoice``, ``key``, etc.
7
+ """