basyx commited on
Commit
a1d29d8
·
verified ·
1 Parent(s): dc88df2

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +32 -64
main.py CHANGED
@@ -14,7 +14,7 @@ from utils.job_queue import start_worker, create_job, get_job
14
  from ingestion.resolver import resolve_input
15
 
16
  # ==============================
17
- # AUTH SYSTEM ✅ NEW
18
  # ==============================
19
  from auth.routes import router as auth_router
20
  from auth.database import Base, engine
@@ -45,22 +45,28 @@ from publisher.metadata_engine import generate_metadata
45
  from publisher.thumbnail_engine import generate_thumbnail
46
 
47
  # ==============================
48
- # INIT (LIFESPAN SAFE)
49
  # ==============================
50
  UPLOAD_DIR = "jobs"
51
  os.makedirs(UPLOAD_DIR, exist_ok=True)
52
 
53
 
 
 
 
54
  @asynccontextmanager
55
  async def lifespan(app: FastAPI):
56
 
57
  logger.info("Starting Basyx Whisper V10.1")
58
 
 
59
  Base.metadata.create_all(bind=engine)
60
 
 
61
  start_worker()
62
  init_scheduler()
63
 
 
64
  asyncio.create_task(autonomous_loop())
65
 
66
  yield
@@ -73,9 +79,10 @@ app = FastAPI(
73
  lifespan=lifespan,
74
  )
75
 
76
- # Register Auth Routes
77
  app.include_router(auth_router)
78
 
 
79
  # ==============================
80
  # TASK REGISTRY
81
  # ==============================
@@ -106,7 +113,7 @@ def normalize_task(task: str):
106
 
107
 
108
  # ==============================
109
- # SAFE INPUT RESOLVER
110
  # ==============================
111
  async def safe_resolve(file, source):
112
 
@@ -114,10 +121,11 @@ async def safe_resolve(file, source):
114
  if not file and not source:
115
  return None
116
 
 
117
  return await asyncio.to_thread(
118
  resolve_input,
119
  source,
120
- file,
121
  )
122
 
123
  except Exception as e:
@@ -137,20 +145,17 @@ async def execute_task(video_path, task, payload=None, webhook=None):
137
  if task == "bulk-publish":
138
  return await bulk_execute(payload), None
139
 
 
140
  if task not in ["bulk-publish", "schedule-post"] and not video_path:
141
  return {"error": "No valid input resolved"}, None
142
 
143
  # -------- AUTONOMOUS ----------
144
  if task == "autonomous":
145
- result = await asyncio.to_thread(
146
- run_autonomous_engine, video_path
147
- )
148
  return result, None
149
 
150
  if task == "auto-publish":
151
- auto = await asyncio.to_thread(
152
- run_autonomous_engine, video_path
153
- )
154
  return await dispatch_publish(
155
  variants=auto.get("all_variants", [])
156
  ), None
@@ -166,7 +171,7 @@ async def execute_task(video_path, task, payload=None, webhook=None):
166
  if task == "generate-metadata":
167
  return generate_metadata(video_path), None
168
 
169
- # THUMBNAIL FIX
170
  if task == "generate-thumbnail":
171
 
172
  output_path = os.path.join(
@@ -188,27 +193,17 @@ async def execute_task(video_path, task, payload=None, webhook=None):
188
 
189
  # -------- TRANSCRIBE ----------
190
  if task == "transcribe":
191
- words = await asyncio.to_thread(
192
- transcribe_video,
193
- video_path,
194
- )
195
  return {"words": words}, None
196
 
197
  if task == "subtitles":
198
- words = await asyncio.to_thread(
199
- transcribe_video,
200
- video_path,
201
- )
202
  return {"srt": generate_srt(words)}, None
203
 
204
  # -------- RENDER ----------
205
  if task == "render":
206
 
207
- words = await asyncio.to_thread(
208
- transcribe_video,
209
- video_path,
210
- )
211
-
212
  srt = generate_srt(words)
213
 
214
  output = os.path.join(
@@ -228,40 +223,24 @@ async def execute_task(video_path, task, payload=None, webhook=None):
228
  # -------- HIGHLIGHTS ----------
229
  if task == "highlights":
230
 
231
- words = await asyncio.to_thread(
232
- transcribe_video,
233
- video_path,
234
- )
235
-
236
  highlights = detect_highlights(words) or []
237
 
238
  clips = create_clips(video_path, highlights)
239
 
240
- return {
241
- "clips_created": len(clips)
242
- }, (clips[0] if clips else None)
243
 
244
  if task == "clips":
245
 
246
- words = await asyncio.to_thread(
247
- transcribe_video,
248
- video_path,
249
- )
250
-
251
  highlights = detect_highlights(words) or []
252
 
253
- return {
254
- "clips": create_clips(video_path, highlights)
255
- }, None
256
 
257
- # -------- SCORING ----------
258
  if task == "viral-score":
259
 
260
- words = await asyncio.to_thread(
261
- transcribe_video,
262
- video_path,
263
- )
264
-
265
  segments = detect_highlights(words) or []
266
 
267
  return {
@@ -271,10 +250,7 @@ async def execute_task(video_path, task, payload=None, webhook=None):
271
  # -------- STRATEGY ----------
272
  if task == "strategy":
273
 
274
- words = await asyncio.to_thread(
275
- transcribe_video,
276
- video_path,
277
- )
278
 
279
  script = rewrite_script(words)
280
  persona = predict_audience(words)
@@ -294,7 +270,7 @@ async def execute_task(video_path, task, payload=None, webhook=None):
294
 
295
 
296
  # ==============================
297
- # EXECUTE ROUTER
298
  # ==============================
299
  @app.post("/execute/{task_name}")
300
  async def execute_router(
@@ -312,15 +288,10 @@ async def execute_router(
312
 
313
  payload = {}
314
 
315
- if request.headers.get(
316
- "content-type", ""
317
- ).startswith("application/json"):
318
  payload = await request.json()
319
 
320
- video_path = await safe_resolve(
321
- file,
322
- url_input or source,
323
- )
324
 
325
  result, output = await execute_task(
326
  video_path,
@@ -329,17 +300,14 @@ async def execute_router(
329
  webhook,
330
  )
331
 
332
- if output and os.path.exists(output):
333
  return FileResponse(output)
334
 
335
  return {"task": task, "result": result}
336
 
337
  except Exception as e:
338
  logger.exception(e)
339
- return JSONResponse(
340
- {"error": str(e)},
341
- status_code=500,
342
- )
343
 
344
 
345
  # ==============================
 
14
  from ingestion.resolver import resolve_input
15
 
16
  # ==============================
17
+ # AUTH SYSTEM
18
  # ==============================
19
  from auth.routes import router as auth_router
20
  from auth.database import Base, engine
 
45
  from publisher.thumbnail_engine import generate_thumbnail
46
 
47
  # ==============================
48
+ # INIT
49
  # ==============================
50
  UPLOAD_DIR = "jobs"
51
  os.makedirs(UPLOAD_DIR, exist_ok=True)
52
 
53
 
54
+ # ==============================
55
+ # LIFECYCLE (FIXED)
56
+ # ==============================
57
  @asynccontextmanager
58
  async def lifespan(app: FastAPI):
59
 
60
  logger.info("Starting Basyx Whisper V10.1")
61
 
62
+ # DB init (AUTH)
63
  Base.metadata.create_all(bind=engine)
64
 
65
+ # workers
66
  start_worker()
67
  init_scheduler()
68
 
69
+ # autonomous engine
70
  asyncio.create_task(autonomous_loop())
71
 
72
  yield
 
79
  lifespan=lifespan,
80
  )
81
 
82
+ # AUTH ROUTES
83
  app.include_router(auth_router)
84
 
85
+
86
  # ==============================
87
  # TASK REGISTRY
88
  # ==============================
 
113
 
114
 
115
  # ==============================
116
+ # SAFE INPUT RESOLVER (FIXED CRASH)
117
  # ==============================
118
  async def safe_resolve(file, source):
119
 
 
121
  if not file and not source:
122
  return None
123
 
124
+ # 🔴 FIX: resolve_input expects UploadFile OR path, not raw string confusion
125
  return await asyncio.to_thread(
126
  resolve_input,
127
  source,
128
+ file if isinstance(file, UploadFile) else None,
129
  )
130
 
131
  except Exception as e:
 
145
  if task == "bulk-publish":
146
  return await bulk_execute(payload), None
147
 
148
+ # -------- INPUT GUARD ----------
149
  if task not in ["bulk-publish", "schedule-post"] and not video_path:
150
  return {"error": "No valid input resolved"}, None
151
 
152
  # -------- AUTONOMOUS ----------
153
  if task == "autonomous":
154
+ result = await asyncio.to_thread(run_autonomous_engine, video_path)
 
 
155
  return result, None
156
 
157
  if task == "auto-publish":
158
+ auto = await asyncio.to_thread(run_autonomous_engine, video_path)
 
 
159
  return await dispatch_publish(
160
  variants=auto.get("all_variants", [])
161
  ), None
 
171
  if task == "generate-metadata":
172
  return generate_metadata(video_path), None
173
 
174
+ # -------- THUMBNAIL ----------
175
  if task == "generate-thumbnail":
176
 
177
  output_path = os.path.join(
 
193
 
194
  # -------- TRANSCRIBE ----------
195
  if task == "transcribe":
196
+ words = await asyncio.to_thread(transcribe_video, video_path)
 
 
 
197
  return {"words": words}, None
198
 
199
  if task == "subtitles":
200
+ words = await asyncio.to_thread(transcribe_video, video_path)
 
 
 
201
  return {"srt": generate_srt(words)}, None
202
 
203
  # -------- RENDER ----------
204
  if task == "render":
205
 
206
+ words = await asyncio.to_thread(transcribe_video, video_path)
 
 
 
 
207
  srt = generate_srt(words)
208
 
209
  output = os.path.join(
 
223
  # -------- HIGHLIGHTS ----------
224
  if task == "highlights":
225
 
226
+ words = await asyncio.to_thread(transcribe_video, video_path)
 
 
 
 
227
  highlights = detect_highlights(words) or []
228
 
229
  clips = create_clips(video_path, highlights)
230
 
231
+ return {"clips_created": len(clips)}, (clips[0] if clips else None)
 
 
232
 
233
  if task == "clips":
234
 
235
+ words = await asyncio.to_thread(transcribe_video, video_path)
 
 
 
 
236
  highlights = detect_highlights(words) or []
237
 
238
+ return {"clips": create_clips(video_path, highlights)}, None
 
 
239
 
240
+ # -------- VIRAL SCORE ----------
241
  if task == "viral-score":
242
 
243
+ words = await asyncio.to_thread(transcribe_video, video_path)
 
 
 
 
244
  segments = detect_highlights(words) or []
245
 
246
  return {
 
250
  # -------- STRATEGY ----------
251
  if task == "strategy":
252
 
253
+ words = await asyncio.to_thread(transcribe_video, video_path)
 
 
 
254
 
255
  script = rewrite_script(words)
256
  persona = predict_audience(words)
 
270
 
271
 
272
  # ==============================
273
+ # ROUTER
274
  # ==============================
275
  @app.post("/execute/{task_name}")
276
  async def execute_router(
 
288
 
289
  payload = {}
290
 
291
+ if request.headers.get("content-type", "").startswith("application/json"):
 
 
292
  payload = await request.json()
293
 
294
+ video_path = await safe_resolve(file, url_input or source)
 
 
 
295
 
296
  result, output = await execute_task(
297
  video_path,
 
300
  webhook,
301
  )
302
 
303
+ if output and isinstance(output, str) and os.path.exists(output):
304
  return FileResponse(output)
305
 
306
  return {"task": task, "result": result}
307
 
308
  except Exception as e:
309
  logger.exception(e)
310
+ return JSONResponse({"error": str(e)}, status_code=500)
 
 
 
311
 
312
 
313
  # ==============================