Hammedalmodel commited on
Commit
78570ac
Β·
verified Β·
1 Parent(s): be1973c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +94 -95
app.py CHANGED
@@ -13,10 +13,7 @@ import uvicorn
13
  import subprocess
14
  import shutil
15
  from pathlib import Path
16
- from fastapi import FastAPI, UploadFile, File, Form, HTTPException
17
- from fastapi.responses import JSONResponse
18
- from fastapi.middleware.cors import CORSMiddleware
19
- from gradio.routes import mount_gradio_app
20
 
21
 
22
  def wrap_text(text, max_line_length=29):
@@ -392,89 +389,6 @@ def process_alignment(media_file, text_file, language, progress=gr.Progress()):
392
  print(f"Debug: Error cleaning up temporary files: {cleanup_error}")
393
 
394
 
395
- # Create FastAPI instance
396
- fastapi_app = FastAPI()
397
-
398
- fastapi_app.add_middleware(
399
- CORSMiddleware,
400
- allow_origins=["*"],
401
- allow_credentials=True,
402
- allow_methods=["*"],
403
- allow_headers=["*"],
404
- )
405
-
406
- @fastapi_app.post("/align")
407
- async def align_api(
408
- media_file: UploadFile = File(...),
409
- text_file: UploadFile = File(...),
410
- language: str = Form(default="en")
411
- ):
412
- try:
413
- # Validate text file
414
- if not text_file.filename.endswith(".txt"):
415
- raise HTTPException(
416
- status_code=400,
417
- detail="Text file must be a .txt file"
418
- )
419
-
420
- # Check if media file is supported
421
- media_filename = media_file.filename.lower()
422
- audio_extensions = {'.wav', '.mp3', '.flac', '.aac', '.ogg', '.wma', '.m4a', '.opus'}
423
- video_extensions = {'.mp4', '.avi', '.mkv', '.mov', '.wmv', '.flv', '.webm', '.m4v', '.3gp', '.mpg', '.mpeg'}
424
-
425
- file_ext = Path(media_filename).suffix.lower()
426
- if file_ext not in audio_extensions and file_ext not in video_extensions:
427
- raise HTTPException(
428
- status_code=400,
429
- detail=f"Unsupported media file format: {file_ext}. Supported formats: {', '.join(sorted(audio_extensions | video_extensions))}"
430
- )
431
-
432
- # Save uploaded files temporarily
433
- with tempfile.NamedTemporaryFile(delete=False, suffix=file_ext) as temp_media:
434
- shutil.copyfileobj(media_file.file, temp_media)
435
- media_path = temp_media.name
436
-
437
- with tempfile.NamedTemporaryFile(delete=False, suffix=".txt", mode='w+', encoding='utf-8') as temp_text:
438
- content = (await text_file.read()).decode('utf-8', errors='ignore')
439
- temp_text.write(content)
440
- temp_text.flush()
441
- text_path = temp_text.name
442
-
443
- # Process alignment
444
- status, df, json_path, summary, srt_path, vtt_path = process_alignment(media_path, text_path, language)
445
-
446
- # Clean up uploaded files
447
- try:
448
- os.unlink(media_path)
449
- os.unlink(text_path)
450
- except Exception as cleanup_error:
451
- print(f"Warning: Error cleaning up uploaded files: {cleanup_error}")
452
-
453
- if "Error" in status or status.startswith("❌"):
454
- raise HTTPException(status_code=500, detail=status)
455
-
456
- response = {
457
- "status": status,
458
- "summary": summary,
459
- "segments": df.to_dict(orient="records") if df is not None else [],
460
- "download_links": {
461
- "alignment_json": json_path,
462
- "srt": srt_path,
463
- "vtt": vtt_path
464
- }
465
- }
466
-
467
- return JSONResponse(status_code=200, content=response)
468
-
469
- except HTTPException:
470
- raise
471
- except Exception as e:
472
- raise HTTPException(
473
- status_code=500,
474
- detail=f"Unexpected server error: {str(e)}"
475
- )
476
-
477
-
478
  def create_interface():
479
 
480
  with gr.Blocks(title="Aeneas Forced Alignment Tool", theme=gr.themes.Soft()) as interface:
@@ -487,8 +401,6 @@ def create_interface():
487
  **Supported formats:**
488
  - **Audio:** WAV, MP3, FLAC, AAC, OGG, WMA, M4A, OPUS
489
  - **Video:** MP4, AVI, MKV, MOV, WMV, FLV, WebM, M4V, 3GP, MPG, MPEG
490
-
491
- **API Access:** Use `/align` endpoint for programmatic access
492
  """)
493
 
494
  with gr.Row():
@@ -582,16 +494,17 @@ def create_interface():
582
  return interface
583
 
584
 
 
 
 
 
585
  def main():
586
  try:
587
- # Create Gradio interface
 
588
  interface = create_interface()
589
-
590
- # Mount FastAPI on Gradio
591
- mount_gradio_app(fastapi_app,interface, path="/api")
592
-
593
  print("πŸš€ Starting Gradio UI on http://localhost:7860")
594
- print("🧠 FastAPI API endpoint available at http://localhost:7860/api/align")
595
 
596
  interface.launch(
597
  server_name="0.0.0.0",
@@ -606,5 +519,91 @@ def main():
606
  print("❌ Error launching application:", e)
607
 
608
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
609
  if __name__ == "__main__":
610
  main()
 
13
  import subprocess
14
  import shutil
15
  from pathlib import Path
16
+
 
 
 
17
 
18
 
19
  def wrap_text(text, max_line_length=29):
 
389
  print(f"Debug: Error cleaning up temporary files: {cleanup_error}")
390
 
391
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
392
  def create_interface():
393
 
394
  with gr.Blocks(title="Aeneas Forced Alignment Tool", theme=gr.themes.Soft()) as interface:
 
401
  **Supported formats:**
402
  - **Audio:** WAV, MP3, FLAC, AAC, OGG, WMA, M4A, OPUS
403
  - **Video:** MP4, AVI, MKV, MOV, WMV, FLV, WebM, M4V, 3GP, MPG, MPEG
 
 
404
  """)
405
 
406
  with gr.Row():
 
494
  return interface
495
 
496
 
497
+ def run_fastapi():
498
+ uvicorn.run(fastapi_app, host="0.0.0.0", port=8000)
499
+
500
+
501
  def main():
502
  try:
503
+ threading.Thread(target=run_fastapi, daemon=True).start()
504
+
505
  interface = create_interface()
 
 
 
 
506
  print("πŸš€ Starting Gradio UI on http://localhost:7860")
507
+ print("🧠 FastAPI JSON endpoint available at http://localhost:8000/align")
508
 
509
  interface.launch(
510
  server_name="0.0.0.0",
 
519
  print("❌ Error launching application:", e)
520
 
521
 
522
+ from fastapi import FastAPI, UploadFile, File, Form, HTTPException
523
+ from fastapi.responses import JSONResponse
524
+ from fastapi.middleware.cors import CORSMiddleware
525
+
526
+ fastapi_app = FastAPI()
527
+
528
+ fastapi_app.add_middleware(
529
+ CORSMiddleware,
530
+ allow_origins=["*"],
531
+ allow_credentials=True,
532
+ allow_methods=["*"],
533
+ allow_headers=["*"],
534
+ )
535
+
536
+ @fastapi_app.post("/align")
537
+ async def align_api(
538
+ media_file: UploadFile = File(...),
539
+ text_file: UploadFile = File(...),
540
+ language: str = Form(default="en")
541
+ ):
542
+ try:
543
+ # Validate text file
544
+ if not text_file.filename.endswith(".txt"):
545
+ raise HTTPException(
546
+ status_code=400,
547
+ detail="Text file must be a .txt file"
548
+ )
549
+
550
+ # Check if media file is supported
551
+ media_filename = media_file.filename.lower()
552
+ audio_extensions = {'.wav', '.mp3', '.flac', '.aac', '.ogg', '.wma', '.m4a', '.opus'}
553
+ video_extensions = {'.mp4', '.avi', '.mkv', '.mov', '.wmv', '.flv', '.webm', '.m4v', '.3gp', '.mpg', '.mpeg'}
554
+
555
+ file_ext = Path(media_filename).suffix.lower()
556
+ if file_ext not in audio_extensions and file_ext not in video_extensions:
557
+ raise HTTPException(
558
+ status_code=400,
559
+ detail=f"Unsupported media file format: {file_ext}. Supported formats: {', '.join(sorted(audio_extensions | video_extensions))}"
560
+ )
561
+
562
+ # Save uploaded files temporarily
563
+ with tempfile.NamedTemporaryFile(delete=False, suffix=file_ext) as temp_media:
564
+ shutil.copyfileobj(media_file.file, temp_media)
565
+ media_path = temp_media.name
566
+
567
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".txt", mode='w+', encoding='utf-8') as temp_text:
568
+ content = (await text_file.read()).decode('utf-8', errors='ignore')
569
+ temp_text.write(content)
570
+ temp_text.flush()
571
+ text_path = temp_text.name
572
+
573
+ # Process alignment
574
+ status, df, json_path, summary, srt_path, vtt_path = process_alignment(media_path, text_path, language)
575
+
576
+ # Clean up uploaded files
577
+ try:
578
+ os.unlink(media_path)
579
+ os.unlink(text_path)
580
+ except Exception as cleanup_error:
581
+ print(f"Warning: Error cleaning up uploaded files: {cleanup_error}")
582
+
583
+ if "Error" in status or status.startswith("❌"):
584
+ raise HTTPException(status_code=500, detail=status)
585
+
586
+ response = {
587
+ "status": status,
588
+ "summary": summary,
589
+ "segments": df.to_dict(orient="records") if df is not None else [],
590
+ "download_links": {
591
+ "alignment_json": json_path,
592
+ "srt": srt_path,
593
+ "vtt": vtt_path
594
+ }
595
+ }
596
+
597
+ return JSONResponse(status_code=200, content=response)
598
+
599
+ except HTTPException:
600
+ raise
601
+ except Exception as e:
602
+ raise HTTPException(
603
+ status_code=500,
604
+ detail=f"Unexpected server error: {str(e)}"
605
+ )
606
+
607
+
608
  if __name__ == "__main__":
609
  main()