deepctl-cmd-keys 0.0.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,63 @@
1
+ Metadata-Version: 2.4
2
+ Name: deepctl-cmd-keys
3
+ Version: 0.0.2
4
+ Summary: API keys management command for deepctl
5
+ Author-email: Deepgram <devrel@deepgram.com>
6
+ Maintainer-email: Deepgram <devrel@deepgram.com>
7
+ License-Expression: MIT
8
+ Keywords: deepgram,cli,keys,api-keys
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
+
22
+ # deepctl-cmd-keys
23
+
24
+ > Part of [deepctl](https://github.com/deepgram/cli) — Official Deepgram CLI
25
+
26
+ API keys management command for deepctl
27
+
28
+ ## Installation
29
+
30
+ This package is included with deepctl and does not need to be installed separately.
31
+
32
+ ### Install deepctl
33
+
34
+ ```bash
35
+ # Install with pip
36
+ pip install deepctl
37
+
38
+ # Or install with uv
39
+ uv tool install deepctl
40
+
41
+ # Or install with pipx
42
+ pipx install deepctl
43
+
44
+ # Or run without installing
45
+ uvx deepctl --help
46
+ pipx run deepctl --help
47
+ ```
48
+
49
+ ## Commands
50
+
51
+ | Command | Entry Point |
52
+ |---------|-------------|
53
+ | `deepctl keys` | `deepctl_cmd_keys.command:KeysCommand` |
54
+
55
+ ## Dependencies
56
+
57
+ - `click>=8.0.0`
58
+ - `rich>=13.0.0`
59
+ - `pydantic>=2.0.0`
60
+
61
+ ## License
62
+
63
+ MIT — see [LICENSE](../../LICENSE)
@@ -0,0 +1,42 @@
1
+ # deepctl-cmd-keys
2
+
3
+ > Part of [deepctl](https://github.com/deepgram/cli) — Official Deepgram CLI
4
+
5
+ API keys management command for deepctl
6
+
7
+ ## Installation
8
+
9
+ This package is included with deepctl and does not need to be installed separately.
10
+
11
+ ### Install deepctl
12
+
13
+ ```bash
14
+ # Install with pip
15
+ pip install deepctl
16
+
17
+ # Or install with uv
18
+ uv tool install deepctl
19
+
20
+ # Or install with pipx
21
+ pipx install deepctl
22
+
23
+ # Or run without installing
24
+ uvx deepctl --help
25
+ pipx run deepctl --help
26
+ ```
27
+
28
+ ## Commands
29
+
30
+ | Command | Entry Point |
31
+ |---------|-------------|
32
+ | `deepctl keys` | `deepctl_cmd_keys.command:KeysCommand` |
33
+
34
+ ## Dependencies
35
+
36
+ - `click>=8.0.0`
37
+ - `rich>=13.0.0`
38
+ - `pydantic>=2.0.0`
39
+
40
+ ## License
41
+
42
+ MIT — see [LICENSE](../../LICENSE)
@@ -0,0 +1,40 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "deepctl-cmd-keys"
7
+ version = "0.0.2" # x-release-please-version
8
+ description = "API keys management command for deepctl"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ authors = [{ name = "Deepgram", email = "devrel@deepgram.com" }]
12
+ maintainers = [{ name = "Deepgram", email = "devrel@deepgram.com" }]
13
+ classifiers = [
14
+ "Development Status :: 3 - Alpha",
15
+ "Intended Audience :: Developers",
16
+ "Programming Language :: Python :: 3",
17
+ "Programming Language :: Python :: 3.10",
18
+ "Programming Language :: Python :: 3.11",
19
+ "Programming Language :: Python :: 3.12",
20
+ ]
21
+ keywords = ["deepgram", "cli", "keys", "api-keys"]
22
+ requires-python = ">=3.10"
23
+ dependencies = [
24
+ "deepctl-core>=0.1.10",
25
+ "click>=8.0.0",
26
+ "rich>=13.0.0",
27
+ "pydantic>=2.0.0",
28
+ ]
29
+
30
+ [project.scripts]
31
+
32
+ [project.entry-points."deepctl.commands"]
33
+ keys = "deepctl_cmd_keys.command:KeysCommand"
34
+
35
+ [tool.setuptools]
36
+ package-dir = { "" = "src" }
37
+
38
+ [tool.setuptools.packages.find]
39
+ where = ["src"]
40
+ include = ["deepctl_cmd_keys*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1 @@
1
+ """API keys management command for deepctl."""
@@ -0,0 +1,296 @@
1
+ """API keys management command for deepctl."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from deepctl_core import (
8
+ AuthManager,
9
+ BaseCommand,
10
+ BaseResult,
11
+ Config,
12
+ DeepgramClient,
13
+ )
14
+ from rich.console import Console
15
+ from rich.table import Table
16
+
17
+ from .models import KeyCreatedInfo, KeyInfo, KeysResult
18
+
19
+ console = Console()
20
+
21
+
22
+ class KeysCommand(BaseCommand):
23
+ """Command for managing Deepgram API keys."""
24
+
25
+ name = "keys"
26
+ help = "Manage Deepgram API keys"
27
+ short_help = "Manage API keys"
28
+
29
+ requires_auth = True
30
+ requires_project = True
31
+ ci_friendly = True
32
+
33
+ examples = [
34
+ "dg keys",
35
+ "dg keys --list",
36
+ "dg keys --create --comment 'staging key' --scopes member",
37
+ "dg keys --show KEY_ID",
38
+ "dg keys --delete KEY_ID",
39
+ "dg keys --list --status active",
40
+ ]
41
+ agent_help = (
42
+ "Manage Deepgram API keys for the current project. "
43
+ "List, create, show, and delete API keys. "
44
+ "Requires authentication and a project ID."
45
+ )
46
+
47
+ def get_arguments(self) -> list[dict[str, Any]]:
48
+ return [
49
+ {
50
+ "names": ["--list", "-l"],
51
+ "help": "List all API keys",
52
+ "is_flag": True,
53
+ "is_option": True,
54
+ },
55
+ {
56
+ "names": ["--create", "-c"],
57
+ "help": "Create a new API key",
58
+ "is_flag": True,
59
+ "is_option": True,
60
+ },
61
+ {
62
+ "names": ["--show", "-s"],
63
+ "help": "Show details for a specific key",
64
+ "type": str,
65
+ "is_option": True,
66
+ },
67
+ {
68
+ "names": ["--delete", "-d"],
69
+ "help": "Delete an API key",
70
+ "type": str,
71
+ "is_option": True,
72
+ },
73
+ {
74
+ "names": ["--comment"],
75
+ "help": "Comment/label for new key",
76
+ "type": str,
77
+ "is_option": True,
78
+ },
79
+ {
80
+ "names": ["--scopes"],
81
+ "help": "Comma-separated scopes for new key (default: member)",
82
+ "type": str,
83
+ "is_option": True,
84
+ "default": "member",
85
+ },
86
+ {
87
+ "names": ["--expiration-date"],
88
+ "help": "Expiration date for new key (ISO format)",
89
+ "type": str,
90
+ "is_option": True,
91
+ },
92
+ {
93
+ "names": ["--ttl"],
94
+ "help": "Time to live in seconds for new key",
95
+ "type": int,
96
+ "is_option": True,
97
+ },
98
+ {
99
+ "names": ["--tags"],
100
+ "help": "Comma-separated tags for new key",
101
+ "type": str,
102
+ "is_option": True,
103
+ },
104
+ {
105
+ "names": ["--status"],
106
+ "help": "Filter keys by status (active, expired)",
107
+ "type": str,
108
+ "is_option": True,
109
+ },
110
+ {
111
+ "names": ["--project-id", "-p"],
112
+ "help": "Project ID (uses configured project if not provided)",
113
+ "type": str,
114
+ "is_option": True,
115
+ },
116
+ {
117
+ "names": ["--yes", "-y"],
118
+ "help": "Skip confirmation prompts",
119
+ "is_flag": True,
120
+ "is_option": True,
121
+ },
122
+ ]
123
+
124
+ def handle(
125
+ self,
126
+ config: Config,
127
+ auth_manager: AuthManager,
128
+ client: DeepgramClient,
129
+ **kwargs: Any,
130
+ ) -> BaseResult:
131
+ create_key = kwargs.get("create", False)
132
+ show_key = kwargs.get("show")
133
+ delete_key = kwargs.get("delete")
134
+ project_id = kwargs.get("project_id")
135
+
136
+ try:
137
+ if create_key:
138
+ return self._create_key(client, project_id, **kwargs)
139
+ elif show_key:
140
+ return self._show_key(client, show_key, project_id)
141
+ elif delete_key:
142
+ return self._delete_key(
143
+ client, delete_key, project_id, kwargs.get("yes", False)
144
+ )
145
+ else:
146
+ # Default: list keys
147
+ return self._list_keys(client, project_id, kwargs.get("status"))
148
+
149
+ except Exception as e:
150
+ console.print(f"[red]Error:[/red] {e}")
151
+ return BaseResult(status="error", message=str(e))
152
+
153
+ def _list_keys(
154
+ self,
155
+ client: DeepgramClient,
156
+ project_id: str | None,
157
+ status: str | None,
158
+ ) -> BaseResult:
159
+ console.print("[blue]Fetching API keys...[/blue]")
160
+ result = client.list_keys(project_id=project_id, status=status)
161
+
162
+ keys_raw = result.get("api_keys", result.get("keys", []))
163
+ if not keys_raw:
164
+ console.print("[yellow]No API keys found[/yellow]")
165
+ return KeysResult(status="info", message="No keys found")
166
+
167
+ key_models: list[KeyInfo] = []
168
+ table = Table(title="API Keys", show_header=True, header_style="bold blue")
169
+ table.add_column("Comment", style="green")
170
+ table.add_column("Key ID", style="dim")
171
+ table.add_column("Scopes")
172
+ table.add_column("Created")
173
+ table.add_column("Expires")
174
+
175
+ for k in keys_raw:
176
+ # SDK may nest key data under "api_key"
177
+ key_data = k.get("api_key", k) if isinstance(k, dict) else k
178
+ if hasattr(key_data, "__dict__"):
179
+ key_data = key_data.__dict__
180
+
181
+ info = KeyInfo(
182
+ key_id=str(key_data.get("api_key_id", "")),
183
+ comment=str(key_data.get("comment", "")),
184
+ scopes=key_data.get("scopes", []),
185
+ created=str(key_data.get("created", "")),
186
+ expiration_date=str(key_data.get("expiration_date", "") or ""),
187
+ tags=key_data.get("tags", []),
188
+ )
189
+ key_models.append(info)
190
+
191
+ table.add_row(
192
+ info.comment or "(no comment)",
193
+ info.key_id,
194
+ ", ".join(info.scopes) if info.scopes else "-",
195
+ info.created[:10] if info.created else "-",
196
+ info.expiration_date[:10] if info.expiration_date else "never",
197
+ )
198
+
199
+ console.print(table)
200
+ console.print(f"\n[dim]{len(key_models)} key(s) found[/dim]")
201
+
202
+ return KeysResult(status="success", keys=key_models, count=len(key_models))
203
+
204
+ def _create_key(
205
+ self,
206
+ client: DeepgramClient,
207
+ project_id: str | None,
208
+ **kwargs: Any,
209
+ ) -> BaseResult:
210
+ comment = kwargs.get("comment", "")
211
+ scopes_str = kwargs.get("scopes", "member")
212
+ scopes = (
213
+ [s.strip() for s in scopes_str.split(",")] if scopes_str else ["member"]
214
+ )
215
+ expiration = kwargs.get("expiration_date")
216
+ ttl = kwargs.get("ttl")
217
+ tags_str = kwargs.get("tags")
218
+ tags = [t.strip() for t in tags_str.split(",")] if tags_str else None
219
+
220
+ console.print("[blue]Creating API key...[/blue]")
221
+
222
+ result = client.create_key(
223
+ project_id=project_id,
224
+ comment=comment,
225
+ scopes=scopes,
226
+ expiration_date=expiration,
227
+ time_to_live=ttl,
228
+ tags=tags,
229
+ )
230
+
231
+ key_id = result.get("api_key_id", "")
232
+ key_value = result.get("key", "")
233
+
234
+ console.print("[green]API key created successfully[/green]")
235
+ console.print(f" Key ID: {key_id}")
236
+ console.print(f" Comment: {comment or '(none)'}")
237
+ console.print(f" Scopes: {', '.join(scopes)}")
238
+ if key_value:
239
+ console.print(f"\n [bold yellow]Key: {key_value}[/bold yellow]")
240
+ console.print("[dim] Save this key now — it won't be shown again.[/dim]")
241
+
242
+ created = KeyCreatedInfo(
243
+ key_id=key_id,
244
+ key=key_value,
245
+ comment=comment,
246
+ scopes=scopes,
247
+ )
248
+ return KeysResult(status="success", message="Key created", created_key=created)
249
+
250
+ def _show_key(
251
+ self,
252
+ client: DeepgramClient,
253
+ key_id: str,
254
+ project_id: str | None,
255
+ ) -> BaseResult:
256
+ console.print(f"[blue]Fetching key details:[/blue] {key_id}")
257
+ result = client.get_key(key_id, project_id=project_id)
258
+
259
+ key_data = result.get("api_key", result) if isinstance(result, dict) else result
260
+
261
+ info = KeyInfo(
262
+ key_id=str(key_data.get("api_key_id", "")),
263
+ comment=str(key_data.get("comment", "")),
264
+ scopes=key_data.get("scopes", []),
265
+ created=str(key_data.get("created", "")),
266
+ expiration_date=str(key_data.get("expiration_date", "") or ""),
267
+ tags=key_data.get("tags", []),
268
+ )
269
+
270
+ console.print("[green]Key Details:[/green]")
271
+ console.print(f" Key ID: {info.key_id}")
272
+ console.print(f" Comment: {info.comment or '(none)'}")
273
+ console.print(f" Scopes: {', '.join(info.scopes) if info.scopes else '-'}")
274
+ console.print(f" Created: {info.created or '-'}")
275
+ console.print(f" Expires: {info.expiration_date or 'never'}")
276
+ if info.tags:
277
+ console.print(f" Tags: {', '.join(info.tags)}")
278
+
279
+ return KeysResult(status="success", keys=[info], count=1)
280
+
281
+ def _delete_key(
282
+ self,
283
+ client: DeepgramClient,
284
+ key_id: str,
285
+ project_id: str | None,
286
+ yes: bool = False,
287
+ ) -> BaseResult:
288
+ if not yes and not self.confirm(
289
+ f"Delete API key {key_id}? This cannot be undone.", default=False
290
+ ):
291
+ return BaseResult(status="cancelled", message="Cancelled by user")
292
+
293
+ console.print(f"[blue]Deleting API key:[/blue] {key_id}")
294
+ client.delete_key(key_id, project_id=project_id)
295
+ console.print(f"[green]API key {key_id} deleted[/green]")
296
+ return BaseResult(status="success", message=f"Key {key_id} deleted")
@@ -0,0 +1,25 @@
1
+ """Models for keys command."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from deepctl_core import BaseResult
6
+ from pydantic import BaseModel, Field
7
+
8
+
9
+ class KeyInfo(BaseModel):
10
+ key_id: str = ""
11
+ comment: str = ""
12
+ scopes: list[str] = Field(default_factory=list)
13
+ created: str = ""
14
+ expiration_date: str = ""
15
+ tags: list[str] = Field(default_factory=list)
16
+
17
+
18
+ class KeyCreatedInfo(KeyInfo):
19
+ key: str = "" # Only available on creation
20
+
21
+
22
+ class KeysResult(BaseResult):
23
+ keys: list[KeyInfo] = Field(default_factory=list)
24
+ count: int = 0
25
+ created_key: KeyCreatedInfo | None = None
@@ -0,0 +1,63 @@
1
+ Metadata-Version: 2.4
2
+ Name: deepctl-cmd-keys
3
+ Version: 0.0.2
4
+ Summary: API keys management command for deepctl
5
+ Author-email: Deepgram <devrel@deepgram.com>
6
+ Maintainer-email: Deepgram <devrel@deepgram.com>
7
+ License-Expression: MIT
8
+ Keywords: deepgram,cli,keys,api-keys
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
+
22
+ # deepctl-cmd-keys
23
+
24
+ > Part of [deepctl](https://github.com/deepgram/cli) — Official Deepgram CLI
25
+
26
+ API keys management command for deepctl
27
+
28
+ ## Installation
29
+
30
+ This package is included with deepctl and does not need to be installed separately.
31
+
32
+ ### Install deepctl
33
+
34
+ ```bash
35
+ # Install with pip
36
+ pip install deepctl
37
+
38
+ # Or install with uv
39
+ uv tool install deepctl
40
+
41
+ # Or install with pipx
42
+ pipx install deepctl
43
+
44
+ # Or run without installing
45
+ uvx deepctl --help
46
+ pipx run deepctl --help
47
+ ```
48
+
49
+ ## Commands
50
+
51
+ | Command | Entry Point |
52
+ |---------|-------------|
53
+ | `deepctl keys` | `deepctl_cmd_keys.command:KeysCommand` |
54
+
55
+ ## Dependencies
56
+
57
+ - `click>=8.0.0`
58
+ - `rich>=13.0.0`
59
+ - `pydantic>=2.0.0`
60
+
61
+ ## License
62
+
63
+ MIT — see [LICENSE](../../LICENSE)
@@ -0,0 +1,11 @@
1
+ README.md
2
+ pyproject.toml
3
+ src/deepctl_cmd_keys/__init__.py
4
+ src/deepctl_cmd_keys/command.py
5
+ src/deepctl_cmd_keys/models.py
6
+ src/deepctl_cmd_keys.egg-info/PKG-INFO
7
+ src/deepctl_cmd_keys.egg-info/SOURCES.txt
8
+ src/deepctl_cmd_keys.egg-info/dependency_links.txt
9
+ src/deepctl_cmd_keys.egg-info/entry_points.txt
10
+ src/deepctl_cmd_keys.egg-info/requires.txt
11
+ src/deepctl_cmd_keys.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [deepctl.commands]
2
+ keys = deepctl_cmd_keys.command:KeysCommand
@@ -0,0 +1,4 @@
1
+ deepctl-core>=0.1.10
2
+ click>=8.0.0
3
+ rich>=13.0.0
4
+ pydantic>=2.0.0
@@ -0,0 +1 @@
1
+ deepctl_cmd_keys