Spaces:
Running
Running
Fix: reuse provider http client for Kling Motion, fix indentation
Browse files
src/content_engine/api/routes_video.py
CHANGED
|
@@ -344,55 +344,55 @@ async def _generate_kling_motion_video(
|
|
| 344 |
_video_jobs[job_id]["message"] = "Calling Kling Motion Control API..."
|
| 345 |
logger.info("Calling Kling Motion Control: %s", endpoint)
|
| 346 |
|
| 347 |
-
|
| 348 |
-
|
| 349 |
-
|
| 350 |
-
|
| 351 |
-
|
| 352 |
-
|
| 353 |
-
|
| 354 |
-
if resp.status_code != 200:
|
| 355 |
-
error_text = resp.text[:500]
|
| 356 |
-
logger.error("Kling Motion API error: %s", error_text)
|
| 357 |
-
_video_jobs[job_id]["status"] = "failed"
|
| 358 |
-
_video_jobs[job_id]["error"] = f"API error: {error_text[:200]}"
|
| 359 |
-
return
|
| 360 |
|
| 361 |
-
|
| 362 |
-
|
| 363 |
-
logger.
|
|
|
|
|
|
|
|
|
|
| 364 |
|
| 365 |
-
|
| 366 |
-
|
| 367 |
-
|
| 368 |
-
|
| 369 |
-
|
| 370 |
-
|
| 371 |
-
|
| 372 |
-
|
| 373 |
-
|
| 374 |
-
|
| 375 |
-
|
| 376 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 377 |
|
| 378 |
-
|
| 379 |
-
|
| 380 |
|
| 381 |
-
|
| 382 |
-
|
| 383 |
-
|
| 384 |
-
|
| 385 |
-
|
| 386 |
-
|
| 387 |
|
| 388 |
-
|
| 389 |
-
|
| 390 |
-
output_path.write_bytes(r.content)
|
| 391 |
|
| 392 |
-
|
| 393 |
-
|
| 394 |
-
|
| 395 |
-
|
| 396 |
|
| 397 |
except Exception as e:
|
| 398 |
logger.exception("Kling Motion generation failed: %s", e)
|
|
|
|
| 344 |
_video_jobs[job_id]["message"] = "Calling Kling Motion Control API..."
|
| 345 |
logger.info("Calling Kling Motion Control: %s", endpoint)
|
| 346 |
|
| 347 |
+
# Reuse the provider's existing httpx client (avoids SSL reconnect issues)
|
| 348 |
+
http = _wavespeed_provider._http_client
|
| 349 |
+
resp = await http.post(
|
| 350 |
+
endpoint,
|
| 351 |
+
json=payload,
|
| 352 |
+
headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"},
|
| 353 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 354 |
|
| 355 |
+
if resp.status_code != 200:
|
| 356 |
+
error_text = resp.text[:500]
|
| 357 |
+
logger.error("Kling Motion API error: %s", error_text)
|
| 358 |
+
_video_jobs[job_id]["status"] = "failed"
|
| 359 |
+
_video_jobs[job_id]["error"] = f"API error: {error_text[:200]}"
|
| 360 |
+
return
|
| 361 |
|
| 362 |
+
result = resp.json()
|
| 363 |
+
data = result.get("data", result)
|
| 364 |
+
logger.info("Kling Motion API response: %s", str(result)[:300])
|
| 365 |
+
|
| 366 |
+
# Poll if async
|
| 367 |
+
outputs = data.get("outputs", [])
|
| 368 |
+
urls_data = data.get("urls", {})
|
| 369 |
+
if not outputs and urls_data.get("get"):
|
| 370 |
+
_video_jobs[job_id]["message"] = "Waiting for Kling Motion to complete..."
|
| 371 |
+
video_url_out = await _poll_wavespeed_video(urls_data["get"], api_key, job_id, max_attempts=300, interval=5.0)
|
| 372 |
+
elif outputs:
|
| 373 |
+
video_url_out = outputs[0] if isinstance(outputs[0], str) else outputs[0].get("url")
|
| 374 |
+
else:
|
| 375 |
+
_video_jobs[job_id]["status"] = "failed"
|
| 376 |
+
_video_jobs[job_id]["error"] = "No output URL in response"
|
| 377 |
+
return
|
| 378 |
|
| 379 |
+
if not video_url_out:
|
| 380 |
+
return # poll already set status
|
| 381 |
|
| 382 |
+
# Download and save
|
| 383 |
+
_video_jobs[job_id]["message"] = "Downloading video..."
|
| 384 |
+
output_dir = Path(os.environ.get("OUTPUT_DIR", "outputs")) / "videos"
|
| 385 |
+
output_dir.mkdir(parents=True, exist_ok=True)
|
| 386 |
+
filename = f"kling_motion_{job_id}.mp4"
|
| 387 |
+
output_path = output_dir / filename
|
| 388 |
|
| 389 |
+
r = await http.get(video_url_out)
|
| 390 |
+
output_path.write_bytes(r.content)
|
|
|
|
| 391 |
|
| 392 |
+
_video_jobs[job_id]["status"] = "completed"
|
| 393 |
+
_video_jobs[job_id]["filename"] = filename
|
| 394 |
+
_video_jobs[job_id]["message"] = "Done"
|
| 395 |
+
logger.info("Kling Motion video saved: %s", filename)
|
| 396 |
|
| 397 |
except Exception as e:
|
| 398 |
logger.exception("Kling Motion generation failed: %s", e)
|