devin-cli 1.3.5__tar.gz → 1.4.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.
- {devin_cli-1.3.5 → devin_cli-1.4.0}/CHANGELOG.md +21 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/PKG-INFO +43 -6
- {devin_cli-1.3.5 → devin_cli-1.4.0}/README.md +41 -4
- {devin_cli-1.3.5 → devin_cli-1.4.0}/generate_facades.py +7 -1
- {devin_cli-1.3.5 → devin_cli-1.4.0}/pyproject.toml +2 -2
- devin_cli-1.4.0/src/devin_cli/__init__.py +1 -0
- devin_cli-1.4.0/src/devin_cli/api/audit_logs.py +13 -0
- devin_cli-1.4.0/src/devin_cli/api/blueprints.py +13 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/api/client.py +18 -3
- devin_cli-1.4.0/src/devin_cli/api/code_scans.py +13 -0
- devin_cli-1.4.0/src/devin_cli/api/guardrail_violations.py +13 -0
- devin_cli-1.4.0/src/devin_cli/api/ip_access_list.py +13 -0
- devin_cli-1.4.0/src/devin_cli/api/pr_reviews.py +13 -0
- devin_cli-1.4.0/src/devin_cli/api/queue.py +13 -0
- devin_cli-1.4.0/src/devin_cli/api/service_users.py +13 -0
- devin_cli-1.4.0/src/devin_cli/api/tags.py +13 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/api/v1/sessions.py +4 -2
- devin_cli-1.4.0/src/devin_cli/api/v3/audit_logs.py +20 -0
- devin_cli-1.4.0/src/devin_cli/api/v3/blueprints.py +22 -0
- devin_cli-1.4.0/src/devin_cli/api/v3/code_scans.py +20 -0
- devin_cli-1.4.0/src/devin_cli/api/v3/guardrail_violations.py +34 -0
- devin_cli-1.4.0/src/devin_cli/api/v3/ip_access_list.py +18 -0
- devin_cli-1.4.0/src/devin_cli/api/v3/pr_reviews.py +32 -0
- devin_cli-1.4.0/src/devin_cli/api/v3/queue.py +5 -0
- devin_cli-1.4.0/src/devin_cli/api/v3/service_users.py +29 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/api/v3/sessions.py +29 -3
- devin_cli-1.4.0/src/devin_cli/api/v3/tags.py +34 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/cli.py +651 -44
- devin_cli-1.4.0/tests/test_api/test_enterprise_endpoints.py +67 -0
- devin_cli-1.4.0/tests/test_api/test_pr_reviews.py +31 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/tests/test_api/test_sessions.py +24 -0
- devin_cli-1.4.0/tests/test_cli_extended.py +250 -0
- devin_cli-1.3.5/src/devin_cli/__init__.py +0 -1
- devin_cli-1.3.5/tests/test_cli_extended.py +0 -121
- {devin_cli-1.3.5 → devin_cli-1.4.0}/.github/workflows/pypi-publish.yml +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/.gitignore +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/LICENSE +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/assets/logo.png +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/setup.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/api/__init__.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/api/attachments.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/api/consumption.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/api/knowledge.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/api/members.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/api/organizations.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/api/playbooks.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/api/repositories.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/api/schedules.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/api/secrets.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/api/sessions.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/api/v1/__init__.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/api/v1/attachments.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/api/v1/knowledge.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/api/v1/playbooks.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/api/v1/secrets.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/api/v3/__init__.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/api/v3/attachments.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/api/v3/consumption.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/api/v3/knowledge.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/api/v3/members.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/api/v3/organizations.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/api/v3/playbooks.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/api/v3/repositories.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/api/v3/schedules.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/api/v3/secrets.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/src/devin_cli/config.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/tests/__init__.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/tests/conftest.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/tests/test_api/test_attachments.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/tests/test_api/test_knowledge.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/tests/test_api/test_playbooks.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/tests/test_api/test_repositories.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/tests/test_api/test_schedules.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/tests/test_api/test_secrets.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/tests/test_cli.py +0 -0
- {devin_cli-1.3.5 → devin_cli-1.4.0}/tests/test_config.py +0 -0
|
@@ -5,6 +5,27 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.4.0] - 2026-08-01
|
|
9
|
+
### Added
|
|
10
|
+
- **Model Selection & Agent Modes**: Full support for `--devin-mode` / `--mode` / `--model` (`normal`, `fast`, `lite`, `ultra`, `fusion`), `--platform`, `--resumable / --no-resumable`, and `--structured-output-required` on `devin sessions create` and `devin create-session`.
|
|
11
|
+
- **Devin PR Reviews**: Added `devin pr-reviews trigger` and `devin pr-reviews get` to trigger and query pull request code reviews.
|
|
12
|
+
- **On-Demand Session Insights**: Added `devin sessions generate-insights <session_id>` (`POST /v3/organizations/{org_id}/sessions/{devin_id}/insights/generate`).
|
|
13
|
+
- **Organization Session Tags**: Added `devin tags list|append|replace|clear` to manage organization session tag policies.
|
|
14
|
+
- **Snapshot Setup / Blueprints**: Added `devin blueprints list|trigger-build|list-builds` to list blueprints and manage snapshot builds.
|
|
15
|
+
- **Enterprise Security & Operations Commands**:
|
|
16
|
+
- `devin enterprise ip-access-list list|add|replace|clear`
|
|
17
|
+
- `devin enterprise guardrails list`
|
|
18
|
+
- `devin enterprise code-scans findings|metrics|remediate`
|
|
19
|
+
- `devin enterprise queue` (health status)
|
|
20
|
+
- `devin enterprise audit-logs list`
|
|
21
|
+
- `devin enterprise service-users list|create-key|rotate-key|revoke-key`
|
|
22
|
+
- **Session Secrets Flag**: Support for `--session-secret KEY=VALUE` on `sessions create` for temporary session secret injection.
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
- **Beta Enterprise URL Scoping**: Fixed `client.py` URL builder to avoid force-injecting `/organizations/` into `v3beta1/enterprise/` endpoints.
|
|
26
|
+
- **JSON Schema Output Parsing**: Automatically parse `--structured-output-schema` string payloads into valid JSON schema objects to meet API specifications.
|
|
27
|
+
- **Unified `--json` Handling**: Standardized `--json` flag behavior across all new CLI subcommands and improved Rich console output stream handling in `@handle_api_error`.
|
|
28
|
+
|
|
8
29
|
## [1.3.4] - 2026-05-03
|
|
9
30
|
### Fixed
|
|
10
31
|
- **Scheduled Sessions API**: Updated the `schedules create` and `schedules update` commands to map the old `cron` and `title` fields to the new `frequency` and `name` properties required by the API. Added `schedule_type="recurring"` and fixed the update method to correctly use `PATCH`.
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: devin-cli
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: Unofficial CLI for Devin AI - The first AI Software Engineer
|
|
5
5
|
Project-URL: Homepage, https://github.com/revanthpobala/devin-cli
|
|
6
6
|
Project-URL: Repository, https://github.com/revanthpobala/devin-cli.git
|
|
7
7
|
Project-URL: Issues, https://github.com/revanthpobala/devin-cli/issues
|
|
8
|
-
Author-email:
|
|
8
|
+
Author-email: Revanth Pobala <revanthpobala@gmail.com>
|
|
9
9
|
License-Expression: MIT
|
|
10
10
|
License-File: LICENSE
|
|
11
11
|
Keywords: agent,ai,automation,autonomous,cli,cognition,devin,software-engineer,terminal
|
|
@@ -42,6 +42,7 @@ Description-Content-Type: text/markdown
|
|
|
42
42
|
|
|
43
43
|
<p align="center">
|
|
44
44
|
<a href="https://pypi.org/project/devin-cli/"><img src="https://img.shields.io/pypi/v/devin-cli.svg?style=for-the-badge&color=0294DE" alt="PyPI version"></a>
|
|
45
|
+
<a href="https://pepy.tech/project/devin-cli"><img src="https://img.shields.io/pepy/dt/devin-cli?style=for-the-badge&color=4c1" alt="Downloads"></a>
|
|
45
46
|
<a href="https://github.com/revanthpobala/homebrew-tap"><img src="https://img.shields.io/badge/Homebrew-Tap-orange?style=for-the-badge&logo=homebrew" alt="Homebrew Tap"></a>
|
|
46
47
|
<a href="https://github.com/revanthpobala/devin-cli/actions/workflows/pypi-publish.yml"><img src="https://github.com/revanthpobala/devin-cli/actions/workflows/pypi-publish.yml/badge.svg" alt="Build Status"></a>
|
|
47
48
|
</p>
|
|
@@ -161,11 +162,14 @@ Profiles are stored in `~/.config/devin/config.json` — fully isolated includin
|
|
|
161
162
|
| :--- | :--- | :--- |
|
|
162
163
|
| `[prompt]` | arg | Task prompt |
|
|
163
164
|
| `--file`, `-f` | path | Read prompt from file |
|
|
164
|
-
| `--title`, `-t` | str |
|
|
165
|
+
| `--title`, `-t` | str | Custom session title |
|
|
166
|
+
| `--devin-mode`, `--mode`, `--model` | str | Agent mode / model: `normal` \| `fast` \| `lite` \| `ultra` \| `fusion` (v3) |
|
|
167
|
+
| `--platform` | str | VM platform (e.g. `windows`) or outpost pool (v3) |
|
|
168
|
+
| `--resumable` / `--no-resumable` | flag | Preserve session VM state after stopping (v3) |
|
|
165
169
|
| `--wait`, `-w` | flag | Block until session finishes |
|
|
166
170
|
| `--interval` | int | Polling interval for `--wait` (default: 5s) |
|
|
167
171
|
| `--max-acu` | int | ACU spend cap |
|
|
168
|
-
| `--force` | flag | Skip duplicate detection |
|
|
172
|
+
| `--force` | flag | Skip duplicate prompt detection |
|
|
169
173
|
| `--advanced-mode` | str | `analyze` \| `create_playbook` \| `improve_playbook` \| `batch` \| `manage_knowledge` |
|
|
170
174
|
| `--playbook-id` | str | Playbook to apply (v3) |
|
|
171
175
|
| `--child-playbook-id` | str | Playbook for each sub-session in `batch` mode (v3) |
|
|
@@ -174,9 +178,11 @@ Profiles are stored in `~/.config/devin/config.json` — fully isolated includin
|
|
|
174
178
|
| `--repo` | str (repeatable) | Repo URLs to attach (v3) |
|
|
175
179
|
| `--knowledge-id` | str (repeatable) | Knowledge IDs to inject |
|
|
176
180
|
| `--secret-id` | str (repeatable) | Secret IDs to inject (v3) |
|
|
181
|
+
| `--session-secret` | str (repeatable) | Temporary session secret `KEY=VALUE` (v3) |
|
|
177
182
|
| `--session-link` | str (repeatable) | Session URLs as context (v3) |
|
|
178
183
|
| `--attachment-url` | str (repeatable) | Attachment URLs (v3) |
|
|
179
184
|
| `--structured-output-schema` | str | JSON schema for structured response (v3) |
|
|
185
|
+
| `--structured-output-required` | flag | Require structured output tool call (v3) |
|
|
180
186
|
| `--create-as-user-id` | str | Enterprise: impersonate a user (v3) |
|
|
181
187
|
| `--org` | str | Override org ID |
|
|
182
188
|
|
|
@@ -184,6 +190,7 @@ Profiles are stored in `~/.config/devin/config.json` — fully isolated includin
|
|
|
184
190
|
```bash
|
|
185
191
|
# No browser interaction required
|
|
186
192
|
devin sessions create \
|
|
193
|
+
--devin-mode fast \
|
|
187
194
|
--advanced-mode batch \
|
|
188
195
|
--playbook-id <orchestrator-id> \
|
|
189
196
|
--child-playbook-id <worker-id> \
|
|
@@ -191,6 +198,30 @@ devin sessions create \
|
|
|
191
198
|
"Process each file in the attached CSV"
|
|
192
199
|
```
|
|
193
200
|
|
|
201
|
+
### PR Reviews (`devin pr-reviews <cmd>`)
|
|
202
|
+
|
|
203
|
+
| Command | Key Flags | Description |
|
|
204
|
+
| :--- | :--- | :--- |
|
|
205
|
+
| `trigger` | `--pr-url` | Trigger a Devin code review for a pull request |
|
|
206
|
+
| `get` | `--pr-url`, `--repo-path`, `--pr-number` | Get latest review status for a pull request |
|
|
207
|
+
|
|
208
|
+
### Organization Session Tags (`devin tags <cmd>`)
|
|
209
|
+
|
|
210
|
+
| Command | Description |
|
|
211
|
+
| :--- | :--- |
|
|
212
|
+
| `list` | List allowed session tags for the organization |
|
|
213
|
+
| `append` | Append tags to organization allowed list (`--tag`) |
|
|
214
|
+
| `replace` | Replace full set of allowed tags (`--tag`) |
|
|
215
|
+
| `clear` | Clear all allowed tags |
|
|
216
|
+
|
|
217
|
+
### Snapshot Blueprints (`devin blueprints <cmd>`)
|
|
218
|
+
|
|
219
|
+
| Command | Description |
|
|
220
|
+
| :--- | :--- |
|
|
221
|
+
| `list` | List snapshot blueprints for the organization |
|
|
222
|
+
| `trigger-build` | Trigger a manual snapshot build |
|
|
223
|
+
| `list-builds` | List history of snapshot builds |
|
|
224
|
+
|
|
194
225
|
### Knowledge (`devin knowledge <cmd>`)
|
|
195
226
|
|
|
196
227
|
| Command | Description |
|
|
@@ -237,12 +268,18 @@ devin sessions create \
|
|
|
237
268
|
| `upload <file>` | Upload a file |
|
|
238
269
|
| `download <id>` | Download an attachment |
|
|
239
270
|
|
|
240
|
-
### Enterprise (`devin enterprise <cmd>`)
|
|
271
|
+
### Enterprise Management (`devin enterprise <cmd>`)
|
|
241
272
|
|
|
242
|
-
| Command | Description |
|
|
273
|
+
| Command Group / Command | Description |
|
|
243
274
|
| :--- | :--- |
|
|
244
275
|
| `whoami` | Show current identity |
|
|
245
276
|
| `list-orgs` | List accessible organizations |
|
|
277
|
+
| `queue` | Get session queue health status |
|
|
278
|
+
| `audit-logs` | List enterprise audit logs (`--limit`, `--order`) |
|
|
279
|
+
| `ip-access-list` | `list` \| `add` \| `replace` \| `clear` enterprise IP allowlists |
|
|
280
|
+
| `guardrails` | `list` guardrail violations (`--session-id`, `--guardrail-id`) |
|
|
281
|
+
| `code-scans` | `findings` \| `metrics` \| `remediate` code scan findings |
|
|
282
|
+
| `service-users` | `list` service users, `create-key`, `rotate-key`, `revoke-key` |
|
|
246
283
|
|
|
247
284
|
### Chain (`devin chain`)
|
|
248
285
|
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
8
|
<a href="https://pypi.org/project/devin-cli/"><img src="https://img.shields.io/pypi/v/devin-cli.svg?style=for-the-badge&color=0294DE" alt="PyPI version"></a>
|
|
9
|
+
<a href="https://pepy.tech/project/devin-cli"><img src="https://img.shields.io/pepy/dt/devin-cli?style=for-the-badge&color=4c1" alt="Downloads"></a>
|
|
9
10
|
<a href="https://github.com/revanthpobala/homebrew-tap"><img src="https://img.shields.io/badge/Homebrew-Tap-orange?style=for-the-badge&logo=homebrew" alt="Homebrew Tap"></a>
|
|
10
11
|
<a href="https://github.com/revanthpobala/devin-cli/actions/workflows/pypi-publish.yml"><img src="https://github.com/revanthpobala/devin-cli/actions/workflows/pypi-publish.yml/badge.svg" alt="Build Status"></a>
|
|
11
12
|
</p>
|
|
@@ -125,11 +126,14 @@ Profiles are stored in `~/.config/devin/config.json` — fully isolated includin
|
|
|
125
126
|
| :--- | :--- | :--- |
|
|
126
127
|
| `[prompt]` | arg | Task prompt |
|
|
127
128
|
| `--file`, `-f` | path | Read prompt from file |
|
|
128
|
-
| `--title`, `-t` | str |
|
|
129
|
+
| `--title`, `-t` | str | Custom session title |
|
|
130
|
+
| `--devin-mode`, `--mode`, `--model` | str | Agent mode / model: `normal` \| `fast` \| `lite` \| `ultra` \| `fusion` (v3) |
|
|
131
|
+
| `--platform` | str | VM platform (e.g. `windows`) or outpost pool (v3) |
|
|
132
|
+
| `--resumable` / `--no-resumable` | flag | Preserve session VM state after stopping (v3) |
|
|
129
133
|
| `--wait`, `-w` | flag | Block until session finishes |
|
|
130
134
|
| `--interval` | int | Polling interval for `--wait` (default: 5s) |
|
|
131
135
|
| `--max-acu` | int | ACU spend cap |
|
|
132
|
-
| `--force` | flag | Skip duplicate detection |
|
|
136
|
+
| `--force` | flag | Skip duplicate prompt detection |
|
|
133
137
|
| `--advanced-mode` | str | `analyze` \| `create_playbook` \| `improve_playbook` \| `batch` \| `manage_knowledge` |
|
|
134
138
|
| `--playbook-id` | str | Playbook to apply (v3) |
|
|
135
139
|
| `--child-playbook-id` | str | Playbook for each sub-session in `batch` mode (v3) |
|
|
@@ -138,9 +142,11 @@ Profiles are stored in `~/.config/devin/config.json` — fully isolated includin
|
|
|
138
142
|
| `--repo` | str (repeatable) | Repo URLs to attach (v3) |
|
|
139
143
|
| `--knowledge-id` | str (repeatable) | Knowledge IDs to inject |
|
|
140
144
|
| `--secret-id` | str (repeatable) | Secret IDs to inject (v3) |
|
|
145
|
+
| `--session-secret` | str (repeatable) | Temporary session secret `KEY=VALUE` (v3) |
|
|
141
146
|
| `--session-link` | str (repeatable) | Session URLs as context (v3) |
|
|
142
147
|
| `--attachment-url` | str (repeatable) | Attachment URLs (v3) |
|
|
143
148
|
| `--structured-output-schema` | str | JSON schema for structured response (v3) |
|
|
149
|
+
| `--structured-output-required` | flag | Require structured output tool call (v3) |
|
|
144
150
|
| `--create-as-user-id` | str | Enterprise: impersonate a user (v3) |
|
|
145
151
|
| `--org` | str | Override org ID |
|
|
146
152
|
|
|
@@ -148,6 +154,7 @@ Profiles are stored in `~/.config/devin/config.json` — fully isolated includin
|
|
|
148
154
|
```bash
|
|
149
155
|
# No browser interaction required
|
|
150
156
|
devin sessions create \
|
|
157
|
+
--devin-mode fast \
|
|
151
158
|
--advanced-mode batch \
|
|
152
159
|
--playbook-id <orchestrator-id> \
|
|
153
160
|
--child-playbook-id <worker-id> \
|
|
@@ -155,6 +162,30 @@ devin sessions create \
|
|
|
155
162
|
"Process each file in the attached CSV"
|
|
156
163
|
```
|
|
157
164
|
|
|
165
|
+
### PR Reviews (`devin pr-reviews <cmd>`)
|
|
166
|
+
|
|
167
|
+
| Command | Key Flags | Description |
|
|
168
|
+
| :--- | :--- | :--- |
|
|
169
|
+
| `trigger` | `--pr-url` | Trigger a Devin code review for a pull request |
|
|
170
|
+
| `get` | `--pr-url`, `--repo-path`, `--pr-number` | Get latest review status for a pull request |
|
|
171
|
+
|
|
172
|
+
### Organization Session Tags (`devin tags <cmd>`)
|
|
173
|
+
|
|
174
|
+
| Command | Description |
|
|
175
|
+
| :--- | :--- |
|
|
176
|
+
| `list` | List allowed session tags for the organization |
|
|
177
|
+
| `append` | Append tags to organization allowed list (`--tag`) |
|
|
178
|
+
| `replace` | Replace full set of allowed tags (`--tag`) |
|
|
179
|
+
| `clear` | Clear all allowed tags |
|
|
180
|
+
|
|
181
|
+
### Snapshot Blueprints (`devin blueprints <cmd>`)
|
|
182
|
+
|
|
183
|
+
| Command | Description |
|
|
184
|
+
| :--- | :--- |
|
|
185
|
+
| `list` | List snapshot blueprints for the organization |
|
|
186
|
+
| `trigger-build` | Trigger a manual snapshot build |
|
|
187
|
+
| `list-builds` | List history of snapshot builds |
|
|
188
|
+
|
|
158
189
|
### Knowledge (`devin knowledge <cmd>`)
|
|
159
190
|
|
|
160
191
|
| Command | Description |
|
|
@@ -201,12 +232,18 @@ devin sessions create \
|
|
|
201
232
|
| `upload <file>` | Upload a file |
|
|
202
233
|
| `download <id>` | Download an attachment |
|
|
203
234
|
|
|
204
|
-
### Enterprise (`devin enterprise <cmd>`)
|
|
235
|
+
### Enterprise Management (`devin enterprise <cmd>`)
|
|
205
236
|
|
|
206
|
-
| Command | Description |
|
|
237
|
+
| Command Group / Command | Description |
|
|
207
238
|
| :--- | :--- |
|
|
208
239
|
| `whoami` | Show current identity |
|
|
209
240
|
| `list-orgs` | List accessible organizations |
|
|
241
|
+
| `queue` | Get session queue health status |
|
|
242
|
+
| `audit-logs` | List enterprise audit logs (`--limit`, `--order`) |
|
|
243
|
+
| `ip-access-list` | `list` \| `add` \| `replace` \| `clear` enterprise IP allowlists |
|
|
244
|
+
| `guardrails` | `list` guardrail violations (`--session-id`, `--guardrail-id`) |
|
|
245
|
+
| `code-scans` | `findings` \| `metrics` \| `remediate` code scan findings |
|
|
246
|
+
| `service-users` | `list` service users, `create-key`, `rotate-key`, `revoke-key` |
|
|
210
247
|
|
|
211
248
|
### Chain (`devin chain`)
|
|
212
249
|
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import os
|
|
2
2
|
|
|
3
|
-
modules = [
|
|
3
|
+
modules = [
|
|
4
|
+
"attachments", "consumption", "knowledge", "members", "organizations",
|
|
5
|
+
"playbooks", "repositories", "schedules", "secrets", "sessions",
|
|
6
|
+
"pr_reviews", "tags", "blueprints", "ip_access_list", "guardrail_violations",
|
|
7
|
+
"code_scans", "queue", "audit_logs", "service_users"
|
|
8
|
+
]
|
|
4
9
|
|
|
5
10
|
for mod in modules:
|
|
6
11
|
content = f"""from devin_cli.config import config
|
|
@@ -19,3 +24,4 @@ def __getattr__(name):
|
|
|
19
24
|
"""
|
|
20
25
|
with open(f"src/devin_cli/api/{mod}.py", "w") as f:
|
|
21
26
|
f.write(content)
|
|
27
|
+
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "devin-cli"
|
|
3
|
-
version = "1.
|
|
3
|
+
version = "1.4.0"
|
|
4
4
|
description = "Unofficial CLI for Devin AI - The first AI Software Engineer"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [
|
|
7
|
-
{ name = "
|
|
7
|
+
{ name = "Revanth Pobala", email = "revanthpobala@gmail.com" },
|
|
8
8
|
]
|
|
9
9
|
license = "MIT"
|
|
10
10
|
keywords = ["devin", "ai", "agent", "software-engineer", "autonomous", "cli", "terminal", "cognition", "automation"]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.4.0"
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from devin_cli.config import config
|
|
2
|
+
import importlib
|
|
3
|
+
|
|
4
|
+
def _get_impl():
|
|
5
|
+
if config.api_version == "v1":
|
|
6
|
+
try:
|
|
7
|
+
return importlib.import_module(f"devin_cli.api.v1.audit_logs")
|
|
8
|
+
except ImportError:
|
|
9
|
+
raise NotImplementedError(f"'audit_logs' feature is only available in Devin API v3, or is not implemented for v1. Run 'devin configure' to switch your API version to v3.")
|
|
10
|
+
return importlib.import_module(f"devin_cli.api.v3.audit_logs")
|
|
11
|
+
|
|
12
|
+
def __getattr__(name):
|
|
13
|
+
return getattr(_get_impl(), name)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from devin_cli.config import config
|
|
2
|
+
import importlib
|
|
3
|
+
|
|
4
|
+
def _get_impl():
|
|
5
|
+
if config.api_version == "v1":
|
|
6
|
+
try:
|
|
7
|
+
return importlib.import_module(f"devin_cli.api.v1.blueprints")
|
|
8
|
+
except ImportError:
|
|
9
|
+
raise NotImplementedError(f"'blueprints' feature is only available in Devin API v3, or is not implemented for v1. Run 'devin configure' to switch your API version to v3.")
|
|
10
|
+
return importlib.import_module(f"devin_cli.api.v3.blueprints")
|
|
11
|
+
|
|
12
|
+
def __getattr__(name):
|
|
13
|
+
return getattr(_get_impl(), name)
|
|
@@ -99,9 +99,24 @@ class BaseClient:
|
|
|
99
99
|
if "files" in kwargs:
|
|
100
100
|
headers.pop("Content-Type", None)
|
|
101
101
|
|
|
102
|
+
import os
|
|
103
|
+
verify_tls = True
|
|
104
|
+
if os.environ.get("DEVIN_INSECURE_TLS") == "1":
|
|
105
|
+
verify_tls = False
|
|
106
|
+
elif os.environ.get("DEVIN_CA_BUNDLE"):
|
|
107
|
+
verify_tls = os.environ.get("DEVIN_CA_BUNDLE")
|
|
108
|
+
|
|
102
109
|
try:
|
|
103
|
-
with httpx.Client(follow_redirects=
|
|
104
|
-
|
|
110
|
+
with httpx.Client(follow_redirects=True, verify=verify_tls, timeout=httpx.Timeout(120.0)) as client_httpx:
|
|
111
|
+
try:
|
|
112
|
+
response = client_httpx.request(method, url, headers=headers, **kwargs)
|
|
113
|
+
except httpx.RequestError as req_err:
|
|
114
|
+
if verify_tls is not False and ("SSL" in str(type(req_err).__name__) or "certificate" in str(req_err).lower() or isinstance(req_err, httpx.ConnectError)):
|
|
115
|
+
console.print(f"[bold yellow]Warning:[/bold yellow] TLS verification or connection failed ({req_err}). Retrying with verify=False... Set DEVIN_INSECURE_TLS=1 to suppress this warning.")
|
|
116
|
+
with httpx.Client(follow_redirects=True, verify=False, timeout=httpx.Timeout(120.0)) as insecure_client:
|
|
117
|
+
response = insecure_client.request(method, url, headers=headers, **kwargs)
|
|
118
|
+
else:
|
|
119
|
+
raise req_err
|
|
105
120
|
return self._handle_response(response)
|
|
106
121
|
except httpx.RequestError as e:
|
|
107
122
|
raise APIError(f"Network error: {e}")
|
|
@@ -124,7 +139,7 @@ class V3Client(BaseClient):
|
|
|
124
139
|
if endpoint.startswith("v3beta1/"):
|
|
125
140
|
base = config.base_url.replace("/v3", "").replace("/v2", "").replace("/v1", "").rstrip("/")
|
|
126
141
|
url = f"{base}/{endpoint}"
|
|
127
|
-
if config.org_id and "/organizations/" not in url:
|
|
142
|
+
if config.org_id and "/organizations/" not in url and "/enterprise/" not in url:
|
|
128
143
|
url = url.replace("v3beta1/", f"v3beta1/organizations/{config.org_id}/")
|
|
129
144
|
return url
|
|
130
145
|
elif endpoint.startswith("enterprise/"):
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from devin_cli.config import config
|
|
2
|
+
import importlib
|
|
3
|
+
|
|
4
|
+
def _get_impl():
|
|
5
|
+
if config.api_version == "v1":
|
|
6
|
+
try:
|
|
7
|
+
return importlib.import_module(f"devin_cli.api.v1.code_scans")
|
|
8
|
+
except ImportError:
|
|
9
|
+
raise NotImplementedError(f"'code_scans' feature is only available in Devin API v3, or is not implemented for v1. Run 'devin configure' to switch your API version to v3.")
|
|
10
|
+
return importlib.import_module(f"devin_cli.api.v3.code_scans")
|
|
11
|
+
|
|
12
|
+
def __getattr__(name):
|
|
13
|
+
return getattr(_get_impl(), name)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from devin_cli.config import config
|
|
2
|
+
import importlib
|
|
3
|
+
|
|
4
|
+
def _get_impl():
|
|
5
|
+
if config.api_version == "v1":
|
|
6
|
+
try:
|
|
7
|
+
return importlib.import_module(f"devin_cli.api.v1.guardrail_violations")
|
|
8
|
+
except ImportError:
|
|
9
|
+
raise NotImplementedError(f"'guardrail_violations' feature is only available in Devin API v3, or is not implemented for v1. Run 'devin configure' to switch your API version to v3.")
|
|
10
|
+
return importlib.import_module(f"devin_cli.api.v3.guardrail_violations")
|
|
11
|
+
|
|
12
|
+
def __getattr__(name):
|
|
13
|
+
return getattr(_get_impl(), name)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from devin_cli.config import config
|
|
2
|
+
import importlib
|
|
3
|
+
|
|
4
|
+
def _get_impl():
|
|
5
|
+
if config.api_version == "v1":
|
|
6
|
+
try:
|
|
7
|
+
return importlib.import_module(f"devin_cli.api.v1.ip_access_list")
|
|
8
|
+
except ImportError:
|
|
9
|
+
raise NotImplementedError(f"'ip_access_list' feature is only available in Devin API v3, or is not implemented for v1. Run 'devin configure' to switch your API version to v3.")
|
|
10
|
+
return importlib.import_module(f"devin_cli.api.v3.ip_access_list")
|
|
11
|
+
|
|
12
|
+
def __getattr__(name):
|
|
13
|
+
return getattr(_get_impl(), name)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from devin_cli.config import config
|
|
2
|
+
import importlib
|
|
3
|
+
|
|
4
|
+
def _get_impl():
|
|
5
|
+
if config.api_version == "v1":
|
|
6
|
+
try:
|
|
7
|
+
return importlib.import_module(f"devin_cli.api.v1.pr_reviews")
|
|
8
|
+
except ImportError:
|
|
9
|
+
raise NotImplementedError(f"'pr_reviews' feature is only available in Devin API v3, or is not implemented for v1. Run 'devin configure' to switch your API version to v3.")
|
|
10
|
+
return importlib.import_module(f"devin_cli.api.v3.pr_reviews")
|
|
11
|
+
|
|
12
|
+
def __getattr__(name):
|
|
13
|
+
return getattr(_get_impl(), name)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from devin_cli.config import config
|
|
2
|
+
import importlib
|
|
3
|
+
|
|
4
|
+
def _get_impl():
|
|
5
|
+
if config.api_version == "v1":
|
|
6
|
+
try:
|
|
7
|
+
return importlib.import_module(f"devin_cli.api.v1.queue")
|
|
8
|
+
except ImportError:
|
|
9
|
+
raise NotImplementedError(f"'queue' feature is only available in Devin API v3, or is not implemented for v1. Run 'devin configure' to switch your API version to v3.")
|
|
10
|
+
return importlib.import_module(f"devin_cli.api.v3.queue")
|
|
11
|
+
|
|
12
|
+
def __getattr__(name):
|
|
13
|
+
return getattr(_get_impl(), name)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from devin_cli.config import config
|
|
2
|
+
import importlib
|
|
3
|
+
|
|
4
|
+
def _get_impl():
|
|
5
|
+
if config.api_version == "v1":
|
|
6
|
+
try:
|
|
7
|
+
return importlib.import_module(f"devin_cli.api.v1.service_users")
|
|
8
|
+
except ImportError:
|
|
9
|
+
raise NotImplementedError(f"'service_users' feature is only available in Devin API v3, or is not implemented for v1. Run 'devin configure' to switch your API version to v3.")
|
|
10
|
+
return importlib.import_module(f"devin_cli.api.v3.service_users")
|
|
11
|
+
|
|
12
|
+
def __getattr__(name):
|
|
13
|
+
return getattr(_get_impl(), name)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from devin_cli.config import config
|
|
2
|
+
import importlib
|
|
3
|
+
|
|
4
|
+
def _get_impl():
|
|
5
|
+
if config.api_version == "v1":
|
|
6
|
+
try:
|
|
7
|
+
return importlib.import_module(f"devin_cli.api.v1.tags")
|
|
8
|
+
except ImportError:
|
|
9
|
+
raise NotImplementedError(f"'tags' feature is only available in Devin API v3, or is not implemented for v1. Run 'devin configure' to switch your API version to v3.")
|
|
10
|
+
return importlib.import_module(f"devin_cli.api.v3.tags")
|
|
11
|
+
|
|
12
|
+
def __getattr__(name):
|
|
13
|
+
return getattr(_get_impl(), name)
|
|
@@ -55,9 +55,11 @@ def create_session(
|
|
|
55
55
|
def get_session(session_id: str):
|
|
56
56
|
return client.get(f"sessions/{session_id}")
|
|
57
57
|
|
|
58
|
-
def get_session_messages(session_id: str):
|
|
58
|
+
def get_session_messages(session_id: str, limit: int = 100, offset: int = 0):
|
|
59
59
|
resp = get_session(session_id)
|
|
60
|
-
|
|
60
|
+
msgs = resp.get("messages", [])
|
|
61
|
+
# Slice the messages array for basic offset pagination since v1 doesn't support an endpoint
|
|
62
|
+
return {"messages": msgs[offset:offset+limit]}
|
|
61
63
|
|
|
62
64
|
def get_session_insights(session_id: str):
|
|
63
65
|
return {"error": "Insights are not available in the v1 API. Please upgrade to v3."}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
from devin_cli.api.client import client
|
|
3
|
+
|
|
4
|
+
def list_audit_logs(limit: int = 100, after: Optional[str] = None, order: Optional[str] = "desc"):
|
|
5
|
+
"""List enterprise audit logs."""
|
|
6
|
+
params = {"limit": limit}
|
|
7
|
+
if after:
|
|
8
|
+
params["after"] = after
|
|
9
|
+
if order:
|
|
10
|
+
params["order"] = order
|
|
11
|
+
return client.get("enterprise/audit-logs", params=params)
|
|
12
|
+
|
|
13
|
+
def list_org_audit_logs(limit: int = 100, after: Optional[str] = None, order: Optional[str] = "desc"):
|
|
14
|
+
"""List organization audit logs."""
|
|
15
|
+
params = {"limit": limit}
|
|
16
|
+
if after:
|
|
17
|
+
params["after"] = after
|
|
18
|
+
if order:
|
|
19
|
+
params["order"] = order
|
|
20
|
+
return client.get("audit-logs", params=params)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
from devin_cli.api.client import client
|
|
3
|
+
|
|
4
|
+
def list_blueprints():
|
|
5
|
+
"""List blueprints for organization."""
|
|
6
|
+
return client.get("blueprints")
|
|
7
|
+
|
|
8
|
+
def get_blueprint(blueprint_id: str):
|
|
9
|
+
"""Get blueprint by ID."""
|
|
10
|
+
return client.get(f"blueprints/{blueprint_id}")
|
|
11
|
+
|
|
12
|
+
def trigger_build():
|
|
13
|
+
"""Trigger a manual snapshot build for the organization."""
|
|
14
|
+
return client.post("builds")
|
|
15
|
+
|
|
16
|
+
def list_builds():
|
|
17
|
+
"""List snapshot builds for the organization."""
|
|
18
|
+
return client.get("builds")
|
|
19
|
+
|
|
20
|
+
def get_build(build_id: str):
|
|
21
|
+
"""Get snapshot build details."""
|
|
22
|
+
return client.get(f"builds/{build_id}")
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
from devin_cli.api.client import client
|
|
3
|
+
|
|
4
|
+
def list_code_scan_findings(limit: int = 100, after: Optional[str] = None):
|
|
5
|
+
"""List enterprise code scan findings."""
|
|
6
|
+
params = {"limit": limit}
|
|
7
|
+
if after:
|
|
8
|
+
params["after"] = after
|
|
9
|
+
return client.get("v3beta1/enterprise/code-scans/findings", params=params)
|
|
10
|
+
|
|
11
|
+
def get_code_scan_metrics():
|
|
12
|
+
"""Get metrics for enterprise code scans."""
|
|
13
|
+
return client.get("v3beta1/enterprise/code-scans/metrics")
|
|
14
|
+
|
|
15
|
+
def remediate_code_scan_finding(finding_id: str, prompt_override: Optional[str] = None):
|
|
16
|
+
"""Launch a Devin session to remediate a code scan finding."""
|
|
17
|
+
data = {"finding_id": finding_id}
|
|
18
|
+
if prompt_override:
|
|
19
|
+
data["prompt_override"] = prompt_override
|
|
20
|
+
return client.post("v3beta1/enterprise/code-scans/remediate", json=data)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
from devin_cli.api.client import client
|
|
3
|
+
|
|
4
|
+
def list_guardrail_violations(
|
|
5
|
+
limit: int = 100,
|
|
6
|
+
after: Optional[str] = None,
|
|
7
|
+
session_id: Optional[str] = None,
|
|
8
|
+
guardrail_id: Optional[str] = None,
|
|
9
|
+
):
|
|
10
|
+
"""List enterprise guardrail violations."""
|
|
11
|
+
params = {"limit": limit}
|
|
12
|
+
if after:
|
|
13
|
+
params["after"] = after
|
|
14
|
+
if session_id:
|
|
15
|
+
params["session_id"] = session_id
|
|
16
|
+
if guardrail_id:
|
|
17
|
+
params["guardrail_id"] = guardrail_id
|
|
18
|
+
return client.get("v3beta1/enterprise/guardrail-violations", params=params)
|
|
19
|
+
|
|
20
|
+
def list_org_guardrail_violations(
|
|
21
|
+
limit: int = 100,
|
|
22
|
+
after: Optional[str] = None,
|
|
23
|
+
session_id: Optional[str] = None,
|
|
24
|
+
guardrail_id: Optional[str] = None,
|
|
25
|
+
):
|
|
26
|
+
"""List organization guardrail violations."""
|
|
27
|
+
params = {"limit": limit}
|
|
28
|
+
if after:
|
|
29
|
+
params["after"] = after
|
|
30
|
+
if session_id:
|
|
31
|
+
params["session_id"] = session_id
|
|
32
|
+
if guardrail_id:
|
|
33
|
+
params["guardrail_id"] = guardrail_id
|
|
34
|
+
return client.get("v3beta1/guardrail-violations", params=params)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from typing import List
|
|
2
|
+
from devin_cli.api.client import client
|
|
3
|
+
|
|
4
|
+
def get_ip_access_list():
|
|
5
|
+
"""Get enterprise IP access allowlist."""
|
|
6
|
+
return client.get("enterprise/ip-access-list")
|
|
7
|
+
|
|
8
|
+
def replace_ip_access_list(cidr_blocks: List[str]):
|
|
9
|
+
"""Replace entire IP access allowlist."""
|
|
10
|
+
return client.put("enterprise/ip-access-list", json={"ip_ranges": cidr_blocks})
|
|
11
|
+
|
|
12
|
+
def add_ip_access_list(cidr_blocks: List[str]):
|
|
13
|
+
"""Append IP ranges to the enterprise IP access allowlist."""
|
|
14
|
+
return client.post("enterprise/ip-access-list", json={"ip_ranges": cidr_blocks})
|
|
15
|
+
|
|
16
|
+
def clear_ip_access_list():
|
|
17
|
+
"""Clear enterprise IP access allowlist."""
|
|
18
|
+
return client.delete("enterprise/ip-access-list")
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
from devin_cli.api.client import client
|
|
3
|
+
|
|
4
|
+
def trigger_pr_review(pr_url: str):
|
|
5
|
+
"""Trigger a Devin Review for a pull request."""
|
|
6
|
+
return client.post("pr-reviews", json={"pr_url": pr_url})
|
|
7
|
+
|
|
8
|
+
def get_pr_review_status(pr_url: Optional[str] = None, repo_path: Optional[str] = None, pr_number: Optional[int] = None):
|
|
9
|
+
"""Get latest Devin Review status for a PR."""
|
|
10
|
+
params = {}
|
|
11
|
+
if pr_url:
|
|
12
|
+
params["pr_url"] = pr_url
|
|
13
|
+
if repo_path:
|
|
14
|
+
params["repo_path"] = repo_path
|
|
15
|
+
if pr_number:
|
|
16
|
+
params["pr_number"] = pr_number
|
|
17
|
+
return client.get("pr-reviews", params=params)
|
|
18
|
+
|
|
19
|
+
def trigger_enterprise_pr_review(pr_url: str):
|
|
20
|
+
"""Trigger an enterprise-scoped Devin Review."""
|
|
21
|
+
return client.post("enterprise/pr-reviews", json={"pr_url": pr_url})
|
|
22
|
+
|
|
23
|
+
def get_enterprise_pr_review_status(pr_url: Optional[str] = None, repo_path: Optional[str] = None, pr_number: Optional[int] = None):
|
|
24
|
+
"""Get latest enterprise-scoped Devin Review status."""
|
|
25
|
+
params = {}
|
|
26
|
+
if pr_url:
|
|
27
|
+
params["pr_url"] = pr_url
|
|
28
|
+
if repo_path:
|
|
29
|
+
params["repo_path"] = repo_path
|
|
30
|
+
if pr_number:
|
|
31
|
+
params["pr_number"] = pr_number
|
|
32
|
+
return client.get("enterprise/pr-reviews", params=params)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
from devin_cli.api.client import client
|
|
3
|
+
|
|
4
|
+
def list_service_users(limit: int = 100, after: Optional[str] = None):
|
|
5
|
+
"""List service users in the enterprise."""
|
|
6
|
+
params = {"limit": limit}
|
|
7
|
+
if after:
|
|
8
|
+
params["after"] = after
|
|
9
|
+
return client.get("enterprise/service-users", params=params)
|
|
10
|
+
|
|
11
|
+
def get_service_user(service_user_id: str):
|
|
12
|
+
"""Get service user details."""
|
|
13
|
+
return client.get(f"enterprise/service-users/{service_user_id}")
|
|
14
|
+
|
|
15
|
+
def list_service_user_api_keys(service_user_id: str):
|
|
16
|
+
"""List API keys for a service user."""
|
|
17
|
+
return client.get(f"enterprise/service-users/{service_user_id}/api-keys")
|
|
18
|
+
|
|
19
|
+
def create_service_user_api_key(service_user_id: str, name: str):
|
|
20
|
+
"""Create a new API key for a service user."""
|
|
21
|
+
return client.post(f"enterprise/service-users/{service_user_id}/api-keys", json={"name": name})
|
|
22
|
+
|
|
23
|
+
def rotate_service_user_api_key(service_user_id: str, key_id: str):
|
|
24
|
+
"""Rotate an API key for a service user."""
|
|
25
|
+
return client.post(f"enterprise/service-users/{service_user_id}/api-keys/{key_id}/rotate")
|
|
26
|
+
|
|
27
|
+
def revoke_service_user_api_key(service_user_id: str, key_id: str):
|
|
28
|
+
"""Revoke an API key for a service user."""
|
|
29
|
+
return client.delete(f"enterprise/service-users/{service_user_id}/api-keys/{key_id}")
|