Hammedalmodel commited on
Commit
e5f5147
Β·
verified Β·
1 Parent(s): 2de5fc3

Update app.py

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