deepctl-cmd-projects 0.1.0__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.
- deepctl_cmd_projects/__init__.py +6 -0
- deepctl_cmd_projects/command.py +350 -0
- deepctl_cmd_projects/models.py +20 -0
- deepctl_cmd_projects-0.1.0.dist-info/METADATA +25 -0
- deepctl_cmd_projects-0.1.0.dist-info/RECORD +8 -0
- deepctl_cmd_projects-0.1.0.dist-info/WHEEL +5 -0
- deepctl_cmd_projects-0.1.0.dist-info/entry_points.txt +2 -0
- deepctl_cmd_projects-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
"""Projects command for deepctl."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from deepctl_core import (
|
|
6
|
+
AuthManager,
|
|
7
|
+
BaseCommand,
|
|
8
|
+
BaseResult,
|
|
9
|
+
Config,
|
|
10
|
+
DeepgramClient,
|
|
11
|
+
)
|
|
12
|
+
from rich.console import Console
|
|
13
|
+
|
|
14
|
+
from .models import ProjectInfo, ProjectsResult
|
|
15
|
+
|
|
16
|
+
console = Console()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class ProjectsCommand(BaseCommand):
|
|
20
|
+
"""Command for managing Deepgram projects."""
|
|
21
|
+
|
|
22
|
+
name = "projects"
|
|
23
|
+
help = "Manage Deepgram projects"
|
|
24
|
+
short_help = "Manage projects"
|
|
25
|
+
|
|
26
|
+
# Projects require authentication
|
|
27
|
+
requires_auth = True
|
|
28
|
+
requires_project = False # Project ID is optional for listing
|
|
29
|
+
ci_friendly = True
|
|
30
|
+
|
|
31
|
+
def get_arguments(self) -> list[dict[str, Any]]:
|
|
32
|
+
"""Get command arguments and options."""
|
|
33
|
+
return [
|
|
34
|
+
{
|
|
35
|
+
"names": ["--list", "-l"],
|
|
36
|
+
"help": "List all projects",
|
|
37
|
+
"is_flag": True,
|
|
38
|
+
"is_option": True,
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"names": ["--create", "-c"],
|
|
42
|
+
"help": "Create a new project",
|
|
43
|
+
"type": str,
|
|
44
|
+
"is_option": True,
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"names": ["--show", "-s"],
|
|
48
|
+
"help": "Show project details",
|
|
49
|
+
"type": str,
|
|
50
|
+
"is_option": True,
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"names": ["--company"],
|
|
54
|
+
"help": "Company name for new project",
|
|
55
|
+
"type": str,
|
|
56
|
+
"is_option": True,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"names": ["--current"],
|
|
60
|
+
"help": "Show current project",
|
|
61
|
+
"is_flag": True,
|
|
62
|
+
"is_option": True,
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"names": ["--set-default"],
|
|
66
|
+
"help": "Set project as default",
|
|
67
|
+
"type": str,
|
|
68
|
+
"is_option": True,
|
|
69
|
+
},
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
def handle(
|
|
73
|
+
self,
|
|
74
|
+
config: Config,
|
|
75
|
+
auth_manager: AuthManager,
|
|
76
|
+
client: DeepgramClient,
|
|
77
|
+
**kwargs: Any,
|
|
78
|
+
) -> BaseResult:
|
|
79
|
+
"""Handle projects command."""
|
|
80
|
+
list_projects = kwargs.get("list", False)
|
|
81
|
+
create_project = kwargs.get("create")
|
|
82
|
+
show_project = kwargs.get("show")
|
|
83
|
+
company = kwargs.get("company")
|
|
84
|
+
show_current = kwargs.get("current", False)
|
|
85
|
+
set_default = kwargs.get("set_default")
|
|
86
|
+
|
|
87
|
+
try:
|
|
88
|
+
if list_projects:
|
|
89
|
+
return self._list_projects(client)
|
|
90
|
+
elif create_project:
|
|
91
|
+
return self._create_project(client, create_project, company)
|
|
92
|
+
elif show_project:
|
|
93
|
+
return self._show_project(client, show_project)
|
|
94
|
+
elif show_current:
|
|
95
|
+
return self._show_current_project(config, auth_manager, client)
|
|
96
|
+
elif set_default:
|
|
97
|
+
return self._set_default_project(
|
|
98
|
+
config, auth_manager, set_default
|
|
99
|
+
)
|
|
100
|
+
else:
|
|
101
|
+
# Default behavior - list projects
|
|
102
|
+
return self._list_projects(client)
|
|
103
|
+
|
|
104
|
+
except Exception as e:
|
|
105
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
106
|
+
return BaseResult(status="error", message=str(e))
|
|
107
|
+
|
|
108
|
+
def _list_projects(
|
|
109
|
+
self, client: DeepgramClient
|
|
110
|
+
) -> ProjectsResult | BaseResult:
|
|
111
|
+
"""List all projects."""
|
|
112
|
+
console.print("[blue]Fetching projects...[/blue]")
|
|
113
|
+
|
|
114
|
+
try:
|
|
115
|
+
result = client.get_projects()
|
|
116
|
+
|
|
117
|
+
# Handle ProjectsResponse object
|
|
118
|
+
projects_raw = []
|
|
119
|
+
if hasattr(result, "projects"):
|
|
120
|
+
projects_raw = result.projects
|
|
121
|
+
elif hasattr(result, "to_dict"):
|
|
122
|
+
result_dict = result.to_dict()
|
|
123
|
+
projects_raw = result_dict.get("projects", [])
|
|
124
|
+
elif hasattr(result, "dict"):
|
|
125
|
+
result_dict = result.dict()
|
|
126
|
+
projects_raw = result_dict.get("projects", [])
|
|
127
|
+
elif isinstance(result, dict):
|
|
128
|
+
projects_raw = result.get("projects", [])
|
|
129
|
+
|
|
130
|
+
if not projects_raw:
|
|
131
|
+
console.print("[yellow]No projects found[/yellow]")
|
|
132
|
+
return ProjectsResult(
|
|
133
|
+
status="info",
|
|
134
|
+
message="No projects found",
|
|
135
|
+
projects=[],
|
|
136
|
+
count=0,
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
project_models: list[ProjectInfo] = []
|
|
140
|
+
console.print(
|
|
141
|
+
f"[green]Found {len(projects_raw)} project(s):[/green]"
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
for proj in projects_raw:
|
|
145
|
+
# Handle project objects that might not be dicts
|
|
146
|
+
project_data = proj
|
|
147
|
+
if hasattr(proj, "__dict__"):
|
|
148
|
+
project_data = proj.__dict__
|
|
149
|
+
elif hasattr(proj, "to_dict"):
|
|
150
|
+
project_data = proj.to_dict()
|
|
151
|
+
elif hasattr(proj, "dict"):
|
|
152
|
+
project_data = proj.dict()
|
|
153
|
+
|
|
154
|
+
info = ProjectInfo(
|
|
155
|
+
project_id=project_data.get("project_id", "N/A"),
|
|
156
|
+
name=project_data.get("name", "Unnamed"),
|
|
157
|
+
company=project_data.get("company"),
|
|
158
|
+
)
|
|
159
|
+
project_models.append(info)
|
|
160
|
+
|
|
161
|
+
console.print(f" • {info.name}")
|
|
162
|
+
console.print(f" ID: {info.project_id}")
|
|
163
|
+
console.print(f" Company: {info.company or 'N/A'}")
|
|
164
|
+
console.print()
|
|
165
|
+
|
|
166
|
+
return ProjectsResult(
|
|
167
|
+
status="success",
|
|
168
|
+
projects=project_models,
|
|
169
|
+
count=len(project_models),
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
except Exception as e:
|
|
173
|
+
console.print(f"[red]Failed to list projects:[/red] {e}")
|
|
174
|
+
return BaseResult(status="error", message=str(e))
|
|
175
|
+
|
|
176
|
+
def _create_project(
|
|
177
|
+
self, client: DeepgramClient, name: str, company: str | None
|
|
178
|
+
) -> ProjectsResult | BaseResult:
|
|
179
|
+
"""Create a new project."""
|
|
180
|
+
console.print(f"[blue]Creating project:[/blue] {name}")
|
|
181
|
+
|
|
182
|
+
if company:
|
|
183
|
+
console.print(f"[dim]Company:[/dim] {company}")
|
|
184
|
+
|
|
185
|
+
try:
|
|
186
|
+
result = client.create_project(name, company)
|
|
187
|
+
|
|
188
|
+
# Handle response object
|
|
189
|
+
result_dict = result
|
|
190
|
+
if hasattr(result, "to_dict"):
|
|
191
|
+
result_dict = result.to_dict()
|
|
192
|
+
elif hasattr(result, "dict"):
|
|
193
|
+
result_dict = result.dict()
|
|
194
|
+
elif hasattr(result, "__dict__"):
|
|
195
|
+
result_dict = result.__dict__
|
|
196
|
+
|
|
197
|
+
if isinstance(result_dict, dict) and "project_id" in result_dict:
|
|
198
|
+
project_id = result_dict["project_id"]
|
|
199
|
+
console.print("[green]✓[/green] Project created successfully")
|
|
200
|
+
console.print(f"[dim]Project ID:[/dim] {project_id}")
|
|
201
|
+
|
|
202
|
+
proj = ProjectInfo(
|
|
203
|
+
project_id=project_id, name=name, company=company
|
|
204
|
+
)
|
|
205
|
+
return ProjectsResult(
|
|
206
|
+
status="success",
|
|
207
|
+
message="Project created successfully",
|
|
208
|
+
projects=[proj],
|
|
209
|
+
count=1,
|
|
210
|
+
)
|
|
211
|
+
else:
|
|
212
|
+
console.print(
|
|
213
|
+
"[yellow]Project creation response missing "
|
|
214
|
+
"project_id[/yellow]"
|
|
215
|
+
)
|
|
216
|
+
return ProjectsResult(
|
|
217
|
+
status="warning",
|
|
218
|
+
message="Created but missing project_id",
|
|
219
|
+
projects=[],
|
|
220
|
+
count=0,
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
except Exception as e:
|
|
224
|
+
console.print(f"[red]Failed to create project:[/red] {e}")
|
|
225
|
+
return BaseResult(status="error", message=str(e))
|
|
226
|
+
|
|
227
|
+
def _show_project(
|
|
228
|
+
self, client: DeepgramClient, project_id: str
|
|
229
|
+
) -> ProjectsResult | BaseResult:
|
|
230
|
+
"""Show details for a specific project."""
|
|
231
|
+
console.print(f"[blue]Fetching project details:[/blue] {project_id}")
|
|
232
|
+
|
|
233
|
+
try:
|
|
234
|
+
result = client.get_project(project_id)
|
|
235
|
+
|
|
236
|
+
# Handle response object
|
|
237
|
+
result_dict = result
|
|
238
|
+
if hasattr(result, "to_dict"):
|
|
239
|
+
result_dict = result.to_dict()
|
|
240
|
+
elif hasattr(result, "dict"):
|
|
241
|
+
result_dict = result.dict()
|
|
242
|
+
elif hasattr(result, "__dict__"):
|
|
243
|
+
result_dict = result.__dict__
|
|
244
|
+
|
|
245
|
+
if isinstance(result_dict, dict) and "name" in result_dict:
|
|
246
|
+
name = result_dict.get("name", "N/A")
|
|
247
|
+
company = result_dict.get("company", "N/A")
|
|
248
|
+
|
|
249
|
+
console.print("[green]Project Details:[/green]")
|
|
250
|
+
console.print(f" Name: {name}")
|
|
251
|
+
console.print(f" ID: {project_id}")
|
|
252
|
+
console.print(f" Company: {company}")
|
|
253
|
+
|
|
254
|
+
proj = ProjectInfo(
|
|
255
|
+
project_id=project_id, name=name, company=company
|
|
256
|
+
)
|
|
257
|
+
return ProjectsResult(
|
|
258
|
+
status="success", projects=[proj], count=1
|
|
259
|
+
)
|
|
260
|
+
else:
|
|
261
|
+
console.print("[yellow]Project details incomplete[/yellow]")
|
|
262
|
+
# Still try to create a project info with what we have
|
|
263
|
+
name = (
|
|
264
|
+
result_dict.get("name", "Unknown")
|
|
265
|
+
if isinstance(result_dict, dict)
|
|
266
|
+
else "Unknown"
|
|
267
|
+
)
|
|
268
|
+
company = (
|
|
269
|
+
result_dict.get("company")
|
|
270
|
+
if isinstance(result_dict, dict)
|
|
271
|
+
else None
|
|
272
|
+
)
|
|
273
|
+
proj = ProjectInfo(
|
|
274
|
+
project_id=project_id, name=name, company=company
|
|
275
|
+
)
|
|
276
|
+
return ProjectsResult(
|
|
277
|
+
status="warning",
|
|
278
|
+
message="Incomplete project data",
|
|
279
|
+
projects=[proj],
|
|
280
|
+
count=1,
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
except Exception as e:
|
|
284
|
+
console.print(f"[red]Failed to get project details:[/red] {e}")
|
|
285
|
+
return BaseResult(status="error", message=str(e))
|
|
286
|
+
|
|
287
|
+
def _show_current_project(
|
|
288
|
+
self, config: Config, auth_manager: AuthManager, client: DeepgramClient
|
|
289
|
+
) -> ProjectsResult | BaseResult:
|
|
290
|
+
"""Show current project details."""
|
|
291
|
+
project_id = auth_manager.get_project_id()
|
|
292
|
+
|
|
293
|
+
if not project_id:
|
|
294
|
+
console.print("[yellow]No current project set[/yellow]")
|
|
295
|
+
console.print(
|
|
296
|
+
"Set a project ID with: "
|
|
297
|
+
"deepctl login --project-id <project_id>"
|
|
298
|
+
)
|
|
299
|
+
console.print("Or use environment variable: DEEPGRAM_PROJECT_ID")
|
|
300
|
+
return BaseResult(status="info", message="No current project set")
|
|
301
|
+
|
|
302
|
+
console.print(f"[blue]Current project ID:[/blue] {project_id}")
|
|
303
|
+
return self._show_project(client, project_id)
|
|
304
|
+
|
|
305
|
+
def _set_default_project(
|
|
306
|
+
self, config: Config, auth_manager: AuthManager, project_id: str
|
|
307
|
+
) -> BaseResult:
|
|
308
|
+
"""Set default project ID."""
|
|
309
|
+
console.print(f"[blue]Setting default project:[/blue] {project_id}")
|
|
310
|
+
|
|
311
|
+
try:
|
|
312
|
+
# Update current profile
|
|
313
|
+
profile_name = config.profile or "default"
|
|
314
|
+
current_profile = config.get_profile(profile_name)
|
|
315
|
+
|
|
316
|
+
# Test if project exists by trying to get it
|
|
317
|
+
client = DeepgramClient(config, auth_manager)
|
|
318
|
+
try:
|
|
319
|
+
client.get_project(project_id)
|
|
320
|
+
console.print("[green]✓[/green] Project ID validated")
|
|
321
|
+
except Exception as e:
|
|
322
|
+
console.print(
|
|
323
|
+
f"[yellow]Warning:[/yellow] Could not validate "
|
|
324
|
+
f"project: {e}"
|
|
325
|
+
)
|
|
326
|
+
if not self.confirm("Continue anyway?", default=False):
|
|
327
|
+
return BaseResult(
|
|
328
|
+
status="cancelled", message="Cancelled by user"
|
|
329
|
+
)
|
|
330
|
+
|
|
331
|
+
# Update profile
|
|
332
|
+
config.create_profile(
|
|
333
|
+
profile_name,
|
|
334
|
+
api_key=current_profile.api_key,
|
|
335
|
+
project_id=project_id,
|
|
336
|
+
base_url=current_profile.base_url,
|
|
337
|
+
)
|
|
338
|
+
|
|
339
|
+
console.print(
|
|
340
|
+
f"[green]✓[/green] Default project set to: {project_id}"
|
|
341
|
+
)
|
|
342
|
+
|
|
343
|
+
return BaseResult(
|
|
344
|
+
status="success",
|
|
345
|
+
message="Default project updated",
|
|
346
|
+
)
|
|
347
|
+
|
|
348
|
+
except Exception as e:
|
|
349
|
+
console.print(f"[red]Failed to set default project:[/red] {e}")
|
|
350
|
+
return BaseResult(status="error", message=str(e))
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""Models for projects command."""
|
|
2
|
+
|
|
3
|
+
from deepctl_core import BaseResult
|
|
4
|
+
from pydantic import BaseModel, Field
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ProjectInfo(BaseModel):
|
|
8
|
+
project_id: str
|
|
9
|
+
name: str
|
|
10
|
+
company: str | None = None
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ProjectsResult(BaseResult):
|
|
14
|
+
projects: list[ProjectInfo] = Field(default_factory=list)
|
|
15
|
+
count: int = 0
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ProjectList(BaseResult):
|
|
19
|
+
projects: list[ProjectInfo] = Field(default_factory=list)
|
|
20
|
+
count: int = 0
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: deepctl-cmd-projects
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Projects 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,projects,management
|
|
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.0
|
|
18
|
+
Requires-Dist: click>=8.0.0
|
|
19
|
+
Requires-Dist: rich>=13.0.0
|
|
20
|
+
Requires-Dist: deepgram-sdk>=3.0.0
|
|
21
|
+
Requires-Dist: pydantic>=2.0.0
|
|
22
|
+
|
|
23
|
+
# deepctl-cmd-projects
|
|
24
|
+
|
|
25
|
+
Projects command for deepctl. This package is an internal component of deepctl and is not intended for standalone use.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
deepctl_cmd_projects/__init__.py,sha256=aTmYdyGousixtieGV4-QdPiwKnvI_39u9areu09rHRA,222
|
|
2
|
+
deepctl_cmd_projects/command.py,sha256=YHvrYNKB3upleVAhOxol1wzm6rrP2VsWDXCwvKfDHfc,12817
|
|
3
|
+
deepctl_cmd_projects/models.py,sha256=dSSX8C8Oe0DAQZPd65PLf1WyJS_kVwgkjG66BC2H9aQ,438
|
|
4
|
+
deepctl_cmd_projects-0.1.0.dist-info/METADATA,sha256=d4RvE3wzDvpTpdcZAKTO9cBEmMWvfIhyP-BLV5fIiOA,917
|
|
5
|
+
deepctl_cmd_projects-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
6
|
+
deepctl_cmd_projects-0.1.0.dist-info/entry_points.txt,sha256=LlxL4YD321McPDZHje5TSg9c0ZmKG7Wjxs1WjFBuMkQ,75
|
|
7
|
+
deepctl_cmd_projects-0.1.0.dist-info/top_level.txt,sha256=Vcw4IHaaQwkgIQvikwPpE4r2UcvKsbmDhZhb5a3b7_c,21
|
|
8
|
+
deepctl_cmd_projects-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
deepctl_cmd_projects
|