Frontend and backend work together fine, complete workflow is implemented

This commit is contained in:
2026-08-01 17:04:03 +05:00
parent e87d8089bf
commit cd3ce0337b
13 changed files with 4499 additions and 86 deletions
+7 -1
View File
@@ -1,11 +1,13 @@
"""FastAPI application entry point."""
import asyncio
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from backend.config import settings
from backend.api import upload, split, status, download
from backend.api.websocket import router as websocket_router
from backend.services import progress_publisher # Import the module
app = FastAPI(
title="Audio Splitter Web API",
@@ -22,6 +24,10 @@ app.add_middleware(
allow_headers=["*"],
)
# Store the main event loop in the progress_publisher module
# This avoids a circular import
progress_publisher.MAIN_LOOP = asyncio.get_running_loop()
# Include routers
app.include_router(upload.router)
app.include_router(split.router)
@@ -37,4 +43,4 @@ async def root():
@app.get("/health")
async def health():
return {"status": "healthy"}
return {"status": "healthy"}
+15 -4
View File
@@ -1,15 +1,20 @@
"""WebSocket progress publisher decouples task manager from WebSocket."""
import json
import asyncio
from typing import Dict, Set
from fastapi import WebSocket
# Active WebSocket connections
# This will be set by main.py when the app starts
MAIN_LOOP = None
active_connections: Dict[str, Set[WebSocket]] = {}
def publish_progress(task_id: str, progress: int, message: str, status: str = "processing"):
"""
Publish progress update to all connected WebSocket clients for a task.
"""
if task_id not in active_connections:
return
@@ -26,10 +31,14 @@ def publish_progress(task_id: str, progress: int, message: str, status: str = "p
to_remove = set()
for websocket in active_connections.get(task_id, set()):
try:
websocket.send_json(data)
# Use the stored main loop, or fallback to getting the current loop
loop = MAIN_LOOP or asyncio.get_running_loop()
asyncio.run_coroutine_threadsafe(websocket.send_json(data), loop)
except Exception:
# Client disconnected or other error
to_remove.add(websocket)
# Clean up disconnected clients
for websocket in to_remove:
active_connections[task_id].discard(websocket)
if task_id in active_connections and not active_connections[task_id]:
@@ -37,13 +46,15 @@ def publish_progress(task_id: str, progress: int, message: str, status: str = "p
def register_connection(task_id: str, websocket: WebSocket):
"""Register a WebSocket connection for a task."""
if task_id not in active_connections:
active_connections[task_id] = set()
active_connections[task_id].add(websocket)
def unregister_connection(task_id: str, websocket: WebSocket):
"""Unregister a WebSocket connection for a task."""
if task_id in active_connections:
active_connections[task_id].discard(websocket)
if not active_connections[task_id]:
del active_connections[task_id]
del active_connections[task_id]
Binary file not shown.
+8 -14
View File
@@ -5,6 +5,7 @@ import sys
import shutil
from pathlib import Path
from typing import List, Dict, Any
import time
from backend.config import settings
from backend.services.task_manager import task_manager
@@ -65,27 +66,17 @@ def run_split_task(task_id: str, tracklist: List[TracklistEntry], options: Dict[
from audio_splitter.core import split_audio
# We need to track progress from the core.
# Since the core doesn't have a progress callback, we'll update progress
# based on track list size (approximate).
total_tracks = len(tracks)
progress_base = 10 # Starting progress after init
task_manager.update_task_with_progress(
task_id, progress=progress_base, message="Starting split..."
task_id, progress=10, message="Starting split..."
)
# Run the split
# The core prints progress to stdout, but we can't easily capture it.
# We'll update progress based on track count.
# For now, we'll report progress after the split completes.
# A more advanced implementation would capture stdout or add a callback.
split_audio(str(input_path), str(output_dir), tracks, args)
# After split completes, get the output files
# Get output files
output_files = FileManager.get_output_files(task_id)
# Final status update
task_manager.update_task_with_progress(
task_id,
progress=100,
@@ -99,6 +90,9 @@ def run_split_task(task_id: str, tracklist: List[TracklistEntry], options: Dict[
tracks=output_files
)
# Give WebSocket time to send the final message
time.sleep(0.5)
except Exception as e:
task_manager.update_task_with_progress(
task_id,
@@ -106,4 +100,4 @@ def run_split_task(task_id: str, tracklist: List[TracklistEntry], options: Dict[
message="Split failed",
status=TaskStatus.ERROR,
error=str(e)
)
)