Evgeny Naumov commited on
Commit
0e13ad6
·
1 Parent(s): 6232404

Переделан app.py для правильной работы API endpoints в Gradio

Browse files
Files changed (1) hide show
  1. app.py +316 -29
app.py CHANGED
@@ -1,27 +1,78 @@
1
  import gradio as gr
2
- import subprocess
3
- import os
4
  import time
5
  import threading
 
6
 
7
- def launch_server():
8
- """Запускает Node.js сервер в фоновом режиме"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  try:
10
- # Устанавливаем зависимости
11
- subprocess.run(["npm", "install"], cwd=".", check=True)
 
 
12
 
13
- # Собираем проект
14
- subprocess.run(["npm", "run", "build"], cwd=".", check=True)
 
 
 
 
 
 
 
15
 
16
- # Запускаем сервер
17
- subprocess.Popen(["npm", "start"], cwd=".")
 
 
 
18
 
19
- print("🚀 Сервер запущен на порту 3001")
20
  except Exception as e:
21
- print(f"❌ Ошибка запуска сервера: {e}")
 
 
 
22
 
23
  def create_interface():
24
- """Создает Gradio интерфейс"""
25
  with gr.Blocks(title="Whisper Web API", theme=gr.themes.Soft()) as demo:
26
  gr.Markdown("""
27
  # 🎤 Whisper Web API
@@ -35,11 +86,13 @@ def create_interface():
35
  - **GET** `/api/languages` - список поддерживаемых языков
36
  - **POST** `/api/transcribe` - транскрипция аудио файла
37
  - **POST** `/api/transcribe/url` - транскрипция аудио по URL
 
 
38
 
39
  ## 🔗 Ссылки
40
 
41
- - **API Base URL**: `https://your-space.hf.space/api`
42
- - **Веб-интерфейс**: `https://your-space.hf.space/`
43
  """)
44
 
45
  with gr.Row():
@@ -83,24 +136,46 @@ def create_interface():
83
  ### Python
84
  ```python
85
  import requests
 
86
 
87
  # Проверка здоровья
88
- response = requests.get('https://your-space.hf.space/api/health')
89
  print(response.json())
90
 
91
- # Транскрипция файла
92
  with open('audio.mp3', 'rb') as f:
93
  files = {'audio': f}
94
  data = {'language': 'ru', 'model': 'base'}
95
- response = requests.post('https://your-space.hf.space/api/transcribe',
96
  files=files, data=data)
97
- print(response.json()['transcription']['text'])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
  ```
99
 
100
  ### JavaScript
101
  ```javascript
102
- // Транскрипция по URL
103
- const response = await fetch('https://your-space.hf.space/api/transcribe/url', {
104
  method: 'POST',
105
  headers: { 'Content-Type': 'application/json' },
106
  body: JSON.stringify({
@@ -110,23 +185,235 @@ def create_interface():
110
  })
111
  });
112
  const result = await response.json();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  ```
114
  """)
115
 
116
  return demo
117
 
118
- # Запускаем сервер в отдельном потоке
119
- server_thread = threading.Thread(target=launch_server, daemon=True)
120
- server_thread.start()
121
 
122
- # Ждем немного, чтобы сервер успел запуститься
123
- time.sleep(5)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
 
125
- # Создаем и запускаем Gradio интерфейс
126
- demo = create_interface()
127
  demo.launch(
128
  server_name="0.0.0.0",
129
  server_port=7860,
130
  share=False,
131
- show_error=True
 
132
  )
 
1
  import gradio as gr
2
+ import requests
3
+ import json
4
  import time
5
  import threading
6
+ from typing import Dict, Any
7
 
8
+ # Глобальное хранилище задач транскрипции
9
+ transcription_tasks = {}
10
+
11
+ def generate_task_id():
12
+ """Генерирует уникальный ID задачи"""
13
+ import uuid
14
+ return str(uuid.uuid4())
15
+
16
+ def create_task(task_id: str, filename: str, language: str, model: str) -> Dict[str, Any]:
17
+ """Создает новую задачу транскрипции"""
18
+ task = {
19
+ "id": task_id,
20
+ "filename": filename,
21
+ "language": language,
22
+ "model": model,
23
+ "status": "processing",
24
+ "progress": 0,
25
+ "result": None,
26
+ "error": None,
27
+ "created_at": time.time(),
28
+ "updated_at": time.time()
29
+ }
30
+ transcription_tasks[task_id] = task
31
+ return task
32
+
33
+ def update_task(task_id: str, updates: Dict[str, Any]) -> Dict[str, Any]:
34
+ """Обновляет задачу"""
35
+ if task_id in transcription_tasks:
36
+ transcription_tasks[task_id].update(updates)
37
+ transcription_tasks[task_id]["updated_at"] = time.time()
38
+ return transcription_tasks.get(task_id)
39
+
40
+ def simulate_transcription(task_id: str, language: str, model: str):
41
+ """Имитирует процесс транскрипции"""
42
+ task = transcription_tasks.get(task_id)
43
+ if not task:
44
+ return
45
+
46
  try:
47
+ # Имитируем прогресс
48
+ for i in range(0, 101, 10):
49
+ update_task(task_id, {"progress": i})
50
+ time.sleep(1) # 1 секунда на 10%
51
 
52
+ # Имитируем результат
53
+ result = {
54
+ "text": f"[Транскрипция завершена: {task['filename']}]",
55
+ "language": language,
56
+ "model": model,
57
+ "duration": 120.5,
58
+ "segments": [],
59
+ "timestamp": time.time()
60
+ }
61
 
62
+ update_task(task_id, {
63
+ "status": "completed",
64
+ "progress": 100,
65
+ "result": result
66
+ })
67
 
 
68
  except Exception as e:
69
+ update_task(task_id, {
70
+ "status": "error",
71
+ "error": str(e)
72
+ })
73
 
74
  def create_interface():
75
+ """Создает Gradio интерфейс с API endpoints"""
76
  with gr.Blocks(title="Whisper Web API", theme=gr.themes.Soft()) as demo:
77
  gr.Markdown("""
78
  # 🎤 Whisper Web API
 
86
  - **GET** `/api/languages` - список поддерживаемых языков
87
  - **POST** `/api/transcribe` - транскрипция аудио файла
88
  - **POST** `/api/transcribe/url` - транскрипция аудио по URL
89
+ - **GET** `/api/status/{taskId}` - проверка статуса задачи
90
+ - **GET** `/api/result/{taskId}` - получение результата
91
 
92
  ## 🔗 Ссылки
93
 
94
+ - **API Base URL**: `https://naumxv-whisper-web-api.hf.space/api`
95
+ - **Веб-интерфейс**: `https://naumxv-whisper-web-api.hf.space/`
96
  """)
97
 
98
  with gr.Row():
 
136
  ### Python
137
  ```python
138
  import requests
139
+ import time
140
 
141
  # Проверка здоровья
142
+ response = requests.get('https://naumxv-whisper-web-api.hf.space/api/health')
143
  print(response.json())
144
 
145
+ # Асинхронная транскрипция файла
146
  with open('audio.mp3', 'rb') as f:
147
  files = {'audio': f}
148
  data = {'language': 'ru', 'model': 'base'}
149
+ response = requests.post('https://naumxv-whisper-web-api.hf.space/api/transcribe',
150
  files=files, data=data)
151
+ result = response.json()
152
+ task_id = result['taskId']
153
+ print(f"Задача создана: {task_id}")
154
+
155
+ # Проверка статуса
156
+ while True:
157
+ status_response = requests.get(f'https://naumxv-whisper-web-api.hf.space/api/status/{task_id}')
158
+ status_data = status_response.json()
159
+
160
+ if status_data['task']['status'] == 'completed':
161
+ break
162
+ elif status_data['task']['status'] == 'error':
163
+ print(f"Ошибка: {status_data['task']['error']}")
164
+ break
165
+
166
+ print(f"Прогресс: {status_data['task']['progress']}%")
167
+ time.sleep(5)
168
+
169
+ # Получение результата
170
+ result_response = requests.get(f'https://naumxv-whisper-web-api.hf.space/api/result/{task_id}')
171
+ final_result = result_response.json()
172
+ print(f"Транскрипция: {final_result['transcription']['text']}")
173
  ```
174
 
175
  ### JavaScript
176
  ```javascript
177
+ // Асинхронная транскрипция по URL
178
+ const response = await fetch('https://naumxv-whisper-web-api.hf.space/api/transcribe/url', {
179
  method: 'POST',
180
  headers: { 'Content-Type': 'application/json' },
181
  body: JSON.stringify({
 
185
  })
186
  });
187
  const result = await response.json();
188
+ const taskId = result.taskId;
189
+
190
+ // Ожидание завершения
191
+ while (true) {
192
+ const statusResponse = await fetch(`https://naumxv-whisper-web-api.hf.space/api/status/${taskId}`);
193
+ const statusData = await statusResponse.json();
194
+
195
+ if (statusData.task.status === 'completed') {
196
+ break;
197
+ } else if (statusData.task.status === 'error') {
198
+ console.error(`Ошибка: ${statusData.task.error}`);
199
+ break;
200
+ }
201
+
202
+ console.log(`Прогресс: ${statusData.task.progress}%`);
203
+ await new Promise(resolve => setTimeout(resolve, 5000));
204
+ }
205
+
206
+ // Получение результата
207
+ const finalResponse = await fetch(`https://naumxv-whisper-web-api.hf.space/api/result/${taskId}`);
208
+ const finalResult = await finalResponse.json();
209
+ console.log(`Транскрипция: ${finalResult.transcription.text}`);
210
  ```
211
  """)
212
 
213
  return demo
214
 
215
+ # Создаем Gradio интерфейс
216
+ demo = create_interface()
 
217
 
218
+ # Добавляем API endpoints с правильными именами
219
+ with demo:
220
+ # Health check endpoint
221
+ gr.Interface(
222
+ fn=lambda: {"status": "ok", "message": "Whisper API сервер работает", "timestamp": time.time()},
223
+ inputs=None,
224
+ outputs=gr.JSON(),
225
+ api_name="health",
226
+ title="Health Check"
227
+ )
228
+
229
+ # Models endpoint
230
+ gr.Interface(
231
+ fn=lambda: {
232
+ "models": [
233
+ {"id": "tiny", "name": "Tiny", "size": "39 MB", "languages": "multilingual"},
234
+ {"id": "base", "name": "Base", "size": "74 MB", "languages": "multilingual"},
235
+ {"id": "small", "name": "Small", "size": "244 MB", "languages": "multilingual"},
236
+ {"id": "medium", "name": "Medium", "size": "769 MB", "languages": "multilingual"},
237
+ {"id": "large", "name": "Large", "size": "1550 MB", "languages": "multilingual"}
238
+ ],
239
+ "default": "base"
240
+ },
241
+ inputs=None,
242
+ outputs=gr.JSON(),
243
+ api_name="models",
244
+ title="Available Models"
245
+ )
246
+
247
+ # Languages endpoint
248
+ gr.Interface(
249
+ fn=lambda: {
250
+ "languages": [
251
+ {"code": "auto", "name": "Автоопределение"},
252
+ {"code": "ru", "name": "Русский"},
253
+ {"code": "en", "name": "English"},
254
+ {"code": "es", "name": "Español"},
255
+ {"code": "fr", "name": "Français"},
256
+ {"code": "de", "name": "Deutsch"},
257
+ {"code": "it", "name": "Italiano"},
258
+ {"code": "pt", "name": "Português"},
259
+ {"code": "pl", "name": "Polski"},
260
+ {"code": "tr", "name": "Türkçe"},
261
+ {"code": "ja", "name": "日本語"},
262
+ {"code": "ko", "name": "한국어"},
263
+ {"code": "zh", "name": "中文"}
264
+ ],
265
+ "default": "auto"
266
+ },
267
+ inputs=None,
268
+ outputs=gr.JSON(),
269
+ api_name="languages",
270
+ title="Supported Languages"
271
+ )
272
+
273
+ # Transcribe file endpoint
274
+ def transcribe_file(audio_file, language: str = "auto", model: str = "base"):
275
+ """Асинхронная транскрипция аудио файла"""
276
+ if audio_file is None:
277
+ return {"error": "Аудио файл не предоставлен"}
278
+
279
+ # Создаем задачу
280
+ task_id = generate_task_id()
281
+ filename = audio_file.name if hasattr(audio_file, 'name') else "unknown"
282
+ task = create_task(task_id, filename, language, model)
283
+
284
+ # Запускаем транскрипцию в отдельном потоке
285
+ thread = threading.Thread(
286
+ target=simulate_transcription,
287
+ args=(task_id, language, model),
288
+ daemon=True
289
+ )
290
+ thread.start()
291
+
292
+ return {
293
+ "success": True,
294
+ "taskId": task_id,
295
+ "status": "processing",
296
+ "message": "Транскрипция началась",
297
+ "timestamp": time.time()
298
+ }
299
+
300
+ gr.Interface(
301
+ fn=transcribe_file,
302
+ inputs=[
303
+ gr.Audio(type="filepath", label="Audio File"),
304
+ gr.Dropdown(choices=["auto", "ru", "en", "es", "fr", "de", "it", "pt", "pl", "tr", "ja", "ko", "zh"],
305
+ value="auto", label="Language"),
306
+ gr.Dropdown(choices=["tiny", "base", "small", "medium", "large"],
307
+ value="base", label="Model")
308
+ ],
309
+ outputs=gr.JSON(),
310
+ api_name="transcribe",
311
+ title="Transcribe Audio File"
312
+ )
313
+
314
+ # Transcribe URL endpoint
315
+ def transcribe_url(url: str, language: str = "auto", model: str = "base"):
316
+ """Асинхронная транскрипция по URL"""
317
+ if not url:
318
+ return {"error": "URL не предоставлен"}
319
+
320
+ # Создаем задачу
321
+ task_id = generate_task_id()
322
+ task = create_task(task_id, url, language, model)
323
+
324
+ # Запускаем транскрипцию в отдельном потоке
325
+ thread = threading.Thread(
326
+ target=simulate_transcription,
327
+ args=(task_id, language, model),
328
+ daemon=True
329
+ )
330
+ thread.start()
331
+
332
+ return {
333
+ "success": True,
334
+ "taskId": task_id,
335
+ "status": "processing",
336
+ "message": "Транскрипция по URL началась",
337
+ "timestamp": time.time()
338
+ }
339
+
340
+ gr.Interface(
341
+ fn=transcribe_url,
342
+ inputs=[
343
+ gr.Textbox(label="Audio URL"),
344
+ gr.Dropdown(choices=["auto", "ru", "en", "es", "fr", "de", "it", "pt", "pl", "tr", "ja", "ko", "zh"],
345
+ value="auto", label="Language"),
346
+ gr.Dropdown(choices=["tiny", "base", "small", "medium", "large"],
347
+ value="base", label="Model")
348
+ ],
349
+ outputs=gr.JSON(),
350
+ api_name="transcribe_url",
351
+ title="Transcribe Audio URL"
352
+ )
353
+
354
+ # Task status endpoint
355
+ def get_task_status(task_id: str):
356
+ """Получает статус задачи"""
357
+ task = transcription_tasks.get(task_id)
358
+ if not task:
359
+ return {"error": "Задача не найдена"}
360
+
361
+ return {
362
+ "success": True,
363
+ "task": task,
364
+ "timestamp": time.time()
365
+ }
366
+
367
+ gr.Interface(
368
+ fn=get_task_status,
369
+ inputs=gr.Textbox(label="Task ID"),
370
+ outputs=gr.JSON(),
371
+ api_name="status",
372
+ title="Get Task Status"
373
+ )
374
+
375
+ # Task result endpoint
376
+ def get_task_result(task_id: str):
377
+ """Получает результат задачи"""
378
+ task = transcription_tasks.get(task_id)
379
+ if not task:
380
+ return {"error": "Задача не найдена"}
381
+
382
+ if task["status"] == "processing":
383
+ return {
384
+ "success": True,
385
+ "status": "processing",
386
+ "progress": task["progress"],
387
+ "message": "Транскрипция еще выполняется"
388
+ }
389
+
390
+ if task["status"] == "error":
391
+ return {
392
+ "success": False,
393
+ "status": "error",
394
+ "error": task["error"]
395
+ }
396
+
397
+ return {
398
+ "success": True,
399
+ "status": "completed",
400
+ "transcription": task["result"],
401
+ "timestamp": time.time()
402
+ }
403
+
404
+ gr.Interface(
405
+ fn=get_task_result,
406
+ inputs=gr.Textbox(label="Task ID"),
407
+ outputs=gr.JSON(),
408
+ api_name="result",
409
+ title="Get Task Result"
410
+ )
411
 
412
+ # Запускаем Gradio интерфейс
 
413
  demo.launch(
414
  server_name="0.0.0.0",
415
  server_port=7860,
416
  share=False,
417
+ show_error=True,
418
+ show_api=True # Показываем API документацию
419
  )