3
3
4
4
import json
5
5
import time
6
- from typing import List
7
6
8
7
import typer
9
8
from rich .console import Console
10
- from rich .table import Table
11
9
from rich .progress import Progress , SpinnerColumn , TextColumn
10
+ from rich .table import Table
12
11
13
12
from template_fastapi .models .speech import BatchTranscriptionRequest , TranscriptionStatus
14
13
from template_fastapi .repositories .speeches import SpeechRepository
20
19
21
20
@app .command ()
22
21
def create_transcription (
23
- content_urls : List [str ] = typer .Argument (..., help = "転写するファイルのURL(複数指定可能)" ),
22
+ content_urls : list [str ] = typer .Argument (..., help = "転写するファイルのURL(複数指定可能)" ),
24
23
locale : str = typer .Option ("ja-JP" , "--locale" , "-l" , help = "言語設定" ),
25
24
display_name : str = typer .Option (None , "--name" , "-n" , help = "転写ジョブの表示名" ),
26
25
model : str = typer .Option (None , "--model" , "-m" , help = "使用するモデル" ),
27
26
):
28
27
"""新しい転写ジョブを作成する"""
29
- console .print (f "[bold green]転写ジョブを作成します[/bold green]" )
28
+ console .print ("[bold green]転写ジョブを作成します[/bold green]" )
30
29
console .print (f"ファイルURL: { ', ' .join (content_urls )} " )
31
30
console .print (f"言語設定: { locale } " )
32
-
31
+
33
32
try :
34
33
request = BatchTranscriptionRequest (
35
34
content_urls = content_urls ,
36
35
locale = locale ,
37
36
display_name = display_name or "CLI Batch Transcription" ,
38
- model = model
37
+ model = model ,
39
38
)
40
-
39
+
41
40
response = speech_repo .create_transcription_job (request )
42
-
43
- console .print (f "✅ [bold green]転写ジョブが正常に作成されました[/bold green]" )
41
+
42
+ console .print ("✅ [bold green]転写ジョブが正常に作成されました[/bold green]" )
44
43
console .print (f"ジョブID: { response .job_id } " )
45
44
console .print (f"ステータス: { response .status .value } " )
46
-
45
+
47
46
if response .message :
48
47
console .print (f"メッセージ: { response .message } " )
49
-
48
+
50
49
except Exception as e :
51
50
console .print (f"❌ [bold red]エラー[/bold red]: { str (e )} " )
52
51
@@ -56,22 +55,22 @@ def get_transcription(
56
55
job_id : str = typer .Argument (..., help = "転写ジョブID" ),
57
56
):
58
57
"""転写ジョブの状態を取得する"""
59
- console .print (f "[bold green]転写ジョブの状態を取得します[/bold green]" )
58
+ console .print ("[bold green]転写ジョブの状態を取得します[/bold green]" )
60
59
console .print (f"ジョブID: { job_id } " )
61
-
60
+
62
61
try :
63
62
job = speech_repo .get_transcription_job (job_id )
64
-
65
- console .print (f "\n [bold blue]転写ジョブ情報[/bold blue]:" )
63
+
64
+ console .print ("\n [bold blue]転写ジョブ情報[/bold blue]:" )
66
65
console .print (f"ID: { job .id } " )
67
66
console .print (f"名前: { job .name } " )
68
67
console .print (f"ステータス: { job .status .value } " )
69
68
console .print (f"作成日時: { job .created_date_time } " )
70
69
console .print (f"最終更新日時: { job .last_action_date_time } " )
71
-
70
+
72
71
if job .links :
73
72
console .print (f"リンク: { json .dumps (job .links , indent = 2 , ensure_ascii = False )} " )
74
-
73
+
75
74
except Exception as e :
76
75
console .print (f"❌ [bold red]エラー[/bold red]: { str (e )} " )
77
76
@@ -81,32 +80,30 @@ def get_transcription_files(
81
80
job_id : str = typer .Argument (..., help = "転写ジョブID" ),
82
81
):
83
82
"""転写ジョブのファイル一覧を取得する"""
84
- console .print (f "[bold green]転写ファイル一覧を取得します[/bold green]" )
83
+ console .print ("[bold green]転写ファイル一覧を取得します[/bold green]" )
85
84
console .print (f"ジョブID: { job_id } " )
86
-
85
+
87
86
try :
88
87
files = speech_repo .get_transcription_files (job_id )
89
-
88
+
90
89
if not files :
91
90
console .print ("[yellow]転写ファイルが見つかりませんでした[/yellow]" )
92
91
return
93
-
92
+
94
93
# テーブルで表示
95
94
table = Table (title = "転写ファイル一覧" )
96
95
table .add_column ("名前" , style = "cyan" )
97
96
table .add_column ("種類" , style = "green" )
98
97
table .add_column ("リンク" , style = "yellow" )
99
-
98
+
100
99
for file in files :
101
100
table .add_row (
102
- file .get ("name" , "N/A" ),
103
- file .get ("kind" , "N/A" ),
104
- file .get ("links" , {}).get ("contentUrl" , "N/A" )
101
+ file .get ("name" , "N/A" ), file .get ("kind" , "N/A" ), file .get ("links" , {}).get ("contentUrl" , "N/A" )
105
102
)
106
-
103
+
107
104
console .print (table )
108
105
console .print (f"[bold blue]合計: { len (files )} 件[/bold blue]" )
109
-
106
+
110
107
except Exception as e :
111
108
console .print (f"❌ [bold red]エラー[/bold red]: { str (e )} " )
112
109
@@ -117,36 +114,36 @@ def get_transcription_result(
117
114
save_file : str = typer .Option (None , "--save" , "-s" , help = "結果を保存するファイル名" ),
118
115
):
119
116
"""転写結果を取得する"""
120
- console .print (f "[bold green]転写結果を取得します[/bold green]" )
117
+ console .print ("[bold green]転写結果を取得します[/bold green]" )
121
118
console .print (f"ファイルURL: { file_url } " )
122
-
119
+
123
120
try :
124
121
result = speech_repo .get_transcription_result (file_url )
125
-
126
- console .print (f "\n [bold blue]転写結果[/bold blue]:" )
122
+
123
+ console .print ("\n [bold blue]転写結果[/bold blue]:" )
127
124
console .print (f"ソース: { result .source } " )
128
125
console .print (f"タイムスタンプ: { result .timestamp } " )
129
126
console .print (f"継続時間: { result .duration_in_ticks } " )
130
-
127
+
131
128
if result .combined_recognized_phrases :
132
- console .print (f "\n [bold yellow]統合認識フレーズ[/bold yellow]:" )
129
+ console .print ("\n [bold yellow]統合認識フレーズ[/bold yellow]:" )
133
130
for phrase in result .combined_recognized_phrases :
134
131
console .print (f"- { phrase .get ('display' , 'N/A' )} " )
135
-
132
+
136
133
if result .recognized_phrases :
137
134
console .print (f"\n [bold yellow]認識フレーズ({ len (result .recognized_phrases )} 件)[/bold yellow]:" )
138
135
for i , phrase in enumerate (result .recognized_phrases [:5 ]): # 最初の5件のみ表示
139
- console .print (f"{ i + 1 } . { phrase .get ('display' , 'N/A' )} " )
140
-
136
+ console .print (f"{ i + 1 } . { phrase .get ('display' , 'N/A' )} " )
137
+
141
138
if len (result .recognized_phrases ) > 5 :
142
139
console .print (f"... および { len (result .recognized_phrases ) - 5 } 件の追加フレーズ" )
143
-
140
+
144
141
# ファイルに保存
145
142
if save_file :
146
- with open (save_file , 'w' , encoding = ' utf-8' ) as f :
143
+ with open (save_file , "w" , encoding = " utf-8" ) as f :
147
144
json .dump (result .dict (), f , ensure_ascii = False , indent = 2 , default = str )
148
145
console .print (f"✅ 結果を { save_file } に保存しました" )
149
-
146
+
150
147
except Exception as e :
151
148
console .print (f"❌ [bold red]エラー[/bold red]: { str (e )} " )
152
149
@@ -157,23 +154,23 @@ def delete_transcription(
157
154
force : bool = typer .Option (False , "--force" , "-f" , help = "確認なしで削除" ),
158
155
):
159
156
"""転写ジョブを削除する"""
160
- console .print (f "[bold yellow]転写ジョブを削除します[/bold yellow]" )
157
+ console .print ("[bold yellow]転写ジョブを削除します[/bold yellow]" )
161
158
console .print (f"ジョブID: { job_id } " )
162
-
159
+
163
160
if not force :
164
161
confirm = typer .confirm ("本当に削除しますか?" )
165
162
if not confirm :
166
163
console .print ("削除をキャンセルしました" )
167
164
return
168
-
165
+
169
166
try :
170
167
success = speech_repo .delete_transcription_job (job_id )
171
-
168
+
172
169
if success :
173
170
console .print (f"✅ [bold green]転写ジョブ '{ job_id } ' を正常に削除しました[/bold green]" )
174
171
else :
175
- console .print (f "❌ [bold red]転写ジョブの削除に失敗しました[/bold red]" )
176
-
172
+ console .print ("❌ [bold red]転写ジョブの削除に失敗しました[/bold red]" )
173
+
177
174
except Exception as e :
178
175
console .print (f"❌ [bold red]エラー[/bold red]: { str (e )} " )
179
176
@@ -182,34 +179,34 @@ def delete_transcription(
182
179
def list_transcriptions ():
183
180
"""転写ジョブの一覧を取得する"""
184
181
console .print ("[bold green]転写ジョブ一覧を取得します[/bold green]" )
185
-
182
+
186
183
try :
187
184
jobs = speech_repo .list_transcription_jobs ()
188
-
185
+
189
186
if not jobs :
190
187
console .print ("[yellow]転写ジョブが見つかりませんでした[/yellow]" )
191
188
return
192
-
189
+
193
190
# テーブルで表示
194
191
table = Table (title = "転写ジョブ一覧" )
195
192
table .add_column ("ID" , style = "cyan" )
196
193
table .add_column ("名前" , style = "green" )
197
194
table .add_column ("ステータス" , style = "yellow" )
198
195
table .add_column ("作成日時" , style = "magenta" )
199
196
table .add_column ("最終更新日時" , style = "blue" )
200
-
197
+
201
198
for job in jobs :
202
199
table .add_row (
203
200
job .id ,
204
201
job .name or "N/A" ,
205
202
job .status .value ,
206
203
str (job .created_date_time ) if job .created_date_time else "N/A" ,
207
- str (job .last_action_date_time ) if job .last_action_date_time else "N/A"
204
+ str (job .last_action_date_time ) if job .last_action_date_time else "N/A" ,
208
205
)
209
-
206
+
210
207
console .print (table )
211
208
console .print (f"[bold blue]合計: { len (jobs )} 件[/bold blue]" )
212
-
209
+
213
210
except Exception as e :
214
211
console .print (f"❌ [bold red]エラー[/bold red]: { str (e )} " )
215
212
@@ -221,51 +218,51 @@ def wait_for_completion(
221
218
interval : int = typer .Option (10 , "--interval" , "-i" , help = "チェック間隔(秒)" ),
222
219
):
223
220
"""転写ジョブの完了を待つ"""
224
- console .print (f "[bold green]転写ジョブの完了を待ちます[/bold green]" )
221
+ console .print ("[bold green]転写ジョブの完了を待ちます[/bold green]" )
225
222
console .print (f"ジョブID: { job_id } " )
226
223
console .print (f"タイムアウト: { timeout } 秒" )
227
224
console .print (f"チェック間隔: { interval } 秒" )
228
-
225
+
229
226
start_time = time .time ()
230
-
227
+
231
228
with Progress (
232
229
SpinnerColumn (),
233
230
TextColumn ("[progress.description]{task.description}" ),
234
231
transient = True ,
235
232
) as progress :
236
233
task = progress .add_task (description = "転写処理中..." , total = None )
237
-
234
+
238
235
while time .time () - start_time < timeout :
239
236
try :
240
237
job = speech_repo .get_transcription_job (job_id )
241
-
238
+
242
239
if job .status == TranscriptionStatus .SUCCEEDED :
243
240
progress .update (task , description = "✅ 転写が完了しました" )
244
- console .print (f "✅ [bold green]転写ジョブが正常に完了しました[/bold green]" )
241
+ console .print ("✅ [bold green]転写ジョブが正常に完了しました[/bold green]" )
245
242
console .print (f"ジョブID: { job .id } " )
246
243
console .print (f"最終更新日時: { job .last_action_date_time } " )
247
244
return
248
245
elif job .status == TranscriptionStatus .FAILED :
249
246
progress .update (task , description = "❌ 転写が失敗しました" )
250
- console .print (f "❌ [bold red]転写ジョブが失敗しました[/bold red]" )
247
+ console .print ("❌ [bold red]転写ジョブが失敗しました[/bold red]" )
251
248
console .print (f"ジョブID: { job .id } " )
252
249
return
253
250
elif job .status == TranscriptionStatus .RUNNING :
254
251
progress .update (task , description = "🔄 転写処理中..." )
255
252
else :
256
253
progress .update (task , description = f"⏳ 待機中 ({ job .status .value } )" )
257
-
254
+
258
255
time .sleep (interval )
259
-
256
+
260
257
except Exception as e :
261
258
progress .update (task , description = f"❌ エラー: { str (e )} " )
262
259
console .print (f"❌ [bold red]エラー[/bold red]: { str (e )} " )
263
260
return
264
-
261
+
265
262
# タイムアウト
266
263
console .print (f"⏰ [bold yellow]タイムアウトしました({ timeout } 秒)[/bold yellow]" )
267
264
console .print ("転写ジョブはまだ処理中の可能性があります" )
268
265
269
266
270
267
if __name__ == "__main__" :
271
- app ()
268
+ app ()
0 commit comments