basyx commited on
Commit
1317cf8
·
verified ·
1 Parent(s): d916674

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +95 -38
main.py CHANGED
@@ -6,108 +6,165 @@ import uuid
6
  import gradio as gr
7
 
8
  from utils.logger import logger
9
- from utils.job_queue import create_job, jobs, start_worker
10
 
11
 
 
 
 
 
 
 
12
  UPLOAD_DIR = "jobs"
13
  os.makedirs(UPLOAD_DIR, exist_ok=True)
14
 
15
- app = FastAPI(title="Fast Whisper Production V2")
16
 
 
17
  start_worker()
18
 
19
- # ------------------------------------------------
20
- # API ENDPOINTS
21
- # ------------------------------------------------
 
22
 
23
  @app.post("/render")
24
- async def render(file: UploadFile = File(...)):
 
 
 
25
 
26
- filename = f"{UPLOAD_DIR}/{uuid.uuid4()}_{file.filename}"
 
27
 
28
- with open(filename, "wb") as buffer:
29
  shutil.copyfileobj(file.file, buffer)
30
 
31
- job_id = create_job(filename)
 
 
32
 
33
  return {
34
  "job_id": job_id,
35
- "status_url": f"/status/{job_id}"
 
36
  }
37
 
38
 
 
 
 
 
39
  @app.get("/status/{job_id}")
40
  def status(job_id: str):
41
 
42
- job = jobs.get(job_id)
43
 
44
  if not job:
45
  return {"error": "Job not found"}
46
 
47
- return job
 
 
 
 
 
 
48
 
49
 
 
 
 
 
50
  @app.get("/download/{job_id}")
51
  def download(job_id: str):
52
 
53
- job = jobs.get(job_id)
54
 
55
- if not job or job["status"] != "completed":
56
- return {"error": "Not ready"}
 
 
 
 
 
 
57
 
58
- return FileResponse(job["output"], filename="rendered.mp4")
 
 
 
 
59
 
60
 
61
- # ------------------------------------------------
62
- # GRADIO UI
63
- # ------------------------------------------------
64
 
65
- def ui_render(video):
66
 
67
  if video is None:
68
- return None, "Upload a video"
 
 
 
 
 
69
 
70
- job_id = create_job(video)
71
 
72
- return None, f"Job Started: {job_id}"
73
 
74
 
75
  def ui_status(job_id):
76
 
77
- job = jobs.get(job_id)
78
 
79
  if not job:
80
  return "Job not found", None
81
 
82
- if job["status"] == "completed":
 
 
83
  return "✅ Completed", job["output"]
84
 
85
- if job["status"] == "failed":
86
- return f"❌ {job['error']}", None
 
 
87
 
88
- return f"Processing {job['progress']}%", None
89
 
 
 
 
90
 
91
- with gr.Blocks(title="Fast Whisper Renderer V2") as demo:
92
 
93
- gr.Markdown("# 🎬 Fast Whisper Production V2")
94
 
95
- video = gr.Video()
96
- btn = gr.Button("Start Render")
 
 
 
97
 
98
  job_id_box = gr.Textbox(label="Job ID")
99
- check_btn = gr.Button("Check Status")
100
 
101
- status = gr.Textbox(label="Status")
102
- output_video = gr.Video()
103
 
104
- btn.click(ui_render, inputs=video, outputs=[output_video, job_id_box])
 
 
 
 
105
 
106
- check_btn.click(
107
  ui_status,
108
  inputs=job_id_box,
109
- outputs=[status, output_video],
110
  )
111
 
112
 
 
113
  app = gr.mount_gradio_app(app, demo, path="/")
 
6
  import gradio as gr
7
 
8
  from utils.logger import logger
9
+ from utils.job_queue import start_worker, create_job, get_job
10
 
11
 
12
+ # =====================================================
13
+ # INIT APP
14
+ # =====================================================
15
+
16
+ app = FastAPI(title="Fast Whisper Production V3")
17
+
18
  UPLOAD_DIR = "jobs"
19
  os.makedirs(UPLOAD_DIR, exist_ok=True)
20
 
 
21
 
22
+ # Start background worker ONCE
23
  start_worker()
24
 
25
+
26
+ # =====================================================
27
+ # API: START RENDER JOB
28
+ # =====================================================
29
 
30
  @app.post("/render")
31
+ async def render(
32
+ file: UploadFile = File(...),
33
+ webhook: str | None = None
34
+ ):
35
 
36
+ job_id = str(uuid.uuid4())
37
+ input_path = f"{UPLOAD_DIR}/{job_id}_{file.filename}"
38
 
39
+ with open(input_path, "wb") as buffer:
40
  shutil.copyfileobj(file.file, buffer)
41
 
42
+ logger.info(f"Incoming render request: {job_id}")
43
+
44
+ job_id = create_job(input_path, webhook)
45
 
46
  return {
47
  "job_id": job_id,
48
+ "status_url": f"/status/{job_id}",
49
+ "download_url": f"/download/{job_id}"
50
  }
51
 
52
 
53
+ # =====================================================
54
+ # API: CHECK STATUS
55
+ # =====================================================
56
+
57
  @app.get("/status/{job_id}")
58
  def status(job_id: str):
59
 
60
+ job = get_job(job_id)
61
 
62
  if not job:
63
  return {"error": "Job not found"}
64
 
65
+ return {
66
+ "job_id": job_id,
67
+ "status": job["status"],
68
+ "stage": job.get("stage"),
69
+ "progress": job.get("progress"),
70
+ "error": job.get("error"),
71
+ }
72
 
73
 
74
+ # =====================================================
75
+ # API: DOWNLOAD RESULT
76
+ # =====================================================
77
+
78
  @app.get("/download/{job_id}")
79
  def download(job_id: str):
80
 
81
+ job = get_job(job_id)
82
 
83
+ if not job:
84
+ return {"error": "Job not found"}
85
+
86
+ if job["status"] != "completed":
87
+ return {
88
+ "error": "Job not completed",
89
+ "status": job["status"]
90
+ }
91
 
92
+ return FileResponse(
93
+ job["output"],
94
+ media_type="video/mp4",
95
+ filename="rendered.mp4"
96
+ )
97
 
98
 
99
+ # =====================================================
100
+ # GRADIO BACKEND (UI)
101
+ # =====================================================
102
 
103
+ def ui_upload(video, webhook):
104
 
105
  if video is None:
106
+ return "No video uploaded", None
107
+
108
+ job_id = str(uuid.uuid4())
109
+ path = f"{UPLOAD_DIR}/{job_id}.mp4"
110
+
111
+ shutil.copy(video, path)
112
 
113
+ jid = create_job(path, webhook)
114
 
115
+ return f"Job Started: {jid}", jid
116
 
117
 
118
  def ui_status(job_id):
119
 
120
+ job = get_job(job_id)
121
 
122
  if not job:
123
  return "Job not found", None
124
 
125
+ status = job["status"]
126
+
127
+ if status == "completed":
128
  return "✅ Completed", job["output"]
129
 
130
+ if status == "failed":
131
+ return f"❌ Failed: {job.get('error')}", None
132
+
133
+ return f"Processing... {job.get('progress', 0)}%", None
134
 
 
135
 
136
+ # =====================================================
137
+ # GRADIO UI LAYOUT
138
+ # =====================================================
139
 
140
+ with gr.Blocks(title="Fast Whisper V3 Renderer") as demo:
141
 
142
+ gr.Markdown("# 🎬 Fast Whisper Production V3")
143
 
144
+ with gr.Row():
145
+ video = gr.Video(label="Upload Video")
146
+ webhook = gr.Textbox(label="Webhook URL (optional)")
147
+
148
+ start_btn = gr.Button("Start Render")
149
 
150
  job_id_box = gr.Textbox(label="Job ID")
151
+ status_btn = gr.Button("Check Status")
152
 
153
+ status_out = gr.Textbox(label="Status")
154
+ video_out = gr.Video(label="Output")
155
 
156
+ start_btn.click(
157
+ ui_upload,
158
+ inputs=[video, webhook],
159
+ outputs=[status_out, job_id_box],
160
+ )
161
 
162
+ status_btn.click(
163
  ui_status,
164
  inputs=job_id_box,
165
+ outputs=[status_out, video_out],
166
  )
167
 
168
 
169
+ # Mount Gradio inside FastAPI root
170
  app = gr.mount_gradio_app(app, demo, path="/")