Fix: Avatar/media path resolution and voice clone dependencies

- Remove nltk dependency from step4_assets by inlining _extract_user_id
- Add graceful error handling for step4_assets in podcast-only mode
- Fix media_utils.py to use tenant-aware get_podcast_media_read_dirs()
- Resolves avatar image 404 during scene image generation
This commit is contained in:
ajaysi
2026-04-20 08:01:45 +05:30
parent bfa1b028b3
commit ba9ddbf368
3 changed files with 34 additions and 10 deletions

View File

@@ -9,8 +9,21 @@ from fastapi.responses import FileResponse
from sqlalchemy.orm import Session
from pydantic import BaseModel
from loguru import logger
from .step4_persona_routes import _extract_user_id
from middleware.auth_middleware import get_current_user
def _extract_user_id(user: Dict[str, Any]) -> str:
"""Extract a stable user ID from Clerk-authenticated user payloads.
Prefers 'clerk_user_id' or 'id', falls back to 'user_id', else 'unknown'.
"""
if not isinstance(user, dict):
return 'unknown'
return (
user.get('clerk_user_id')
or user.get('id')
or user.get('user_id')
or 'unknown'
)
import base64
import os
from pathlib import Path

View File

@@ -426,13 +426,15 @@ if PODCAST_ONLY_DEMO_MODE:
podcast_routers = [r for r in CORE_ROUTER_REGISTRY if "podcast" in r.get("features", set())]
logger.info(f"[PODCAST-ONLY] Found {len(podcast_routers)} podcast routers: {[r['name'] for r in podcast_routers]}")
# Force include step4_assets for voice cloning
# Try to include step4_assets for voice cloning (may fail if nltk not installed)
step4_entry = next((r for r in CORE_ROUTER_REGISTRY if r.get("name") == "step4_assets"), None)
if step4_entry:
try:
logger.info(f"[PODCAST-ONLY] Forcing load of step4_assets for voice cloning")
logger.info(f"[PODCAST-ONLY] Attempting to load step4_assets for voice cloning")
router = router_manager._load_router_from_registry(step4_entry)
router_manager.include_router_safely(router, step4_entry["name"], step4_entry.get("include_kwargs"))
except ImportError as e:
logger.warning(f"[PODCAST-ONLY] Skipping step4_assets (missing optional dependency): {e}")
except Exception as e:
logger.error(f"[PODCAST-ONLY] Failed to mount step4_assets: {e}")

View File

@@ -97,13 +97,22 @@ def resolve_media_path(media_url_or_path: str) -> Optional[Path]:
# Prioritize YouTube paths
pass # Already first in list
elif "/api/podcast/" in media_url_or_path:
# Prioritize Podcast paths
search_paths = [
PODCAST_AVATARS_DIR / filename,
PODCAST_IMAGES_DIR / filename,
YOUTUBE_AVATARS_DIR / filename,
YOUTUBE_IMAGES_DIR / filename
]
# Prioritize Podcast paths: use centralized podcast media resolution
try:
# Import the centralized function that checks tenant workspace first
from api.podcast.constants import get_podcast_media_read_dirs
podcast_dirs = get_podcast_media_read_dirs("image")
search_paths = []
for pod_dir in podcast_dirs:
# Add both avatar and image subdirectories
search_paths.append(pod_dir / "avatars" / filename)
search_paths.append(pod_dir / filename)
except ImportError:
# Fallback if podcast constants not available
search_paths = [
PODCAST_AVATARS_DIR / filename,
PODCAST_IMAGES_DIR / filename,
]
# Iterate and find first existing file
for path in search_paths: