Marketeer / helpers /json_utils.py
KPrashanth's picture
Upload 47 files
85ba912 verified
"""
JSON extraction and fallback utilities for video scripting.
We try to pull a JSON object out of a model's response, and if
that fails, we return None so the caller can use a fallback block.
"""
import json
from typing import Any, Dict, Optional
def extract_json_block(text: str) -> Optional[Dict[str, Any]]:
"""
Try to parse a JSON object from the given text.
Strategy:
1. Try json.loads on the whole string.
2. If that fails, look for the first '{' and last '}' and parse that slice.
3. If still failing, return None.
"""
text = text.strip()
if not text:
return None
# 1) raw attempt
try:
obj = json.loads(text)
if isinstance(obj, dict):
return obj
except Exception:
pass
# 2) substring between first '{' and last '}'
start = text.find("{")
end = text.rfind("}")
if start == -1 or end == -1 or end <= start:
return None
candidate = text[start : end + 1]
try:
obj = json.loads(candidate)
if isinstance(obj, dict):
return obj
except Exception:
return None
return None
def fallback_block(beat_title: str) -> Dict[str, Any]:
"""
Provide a safe default block when JSON parsing fails.
The strings here are intentionally generic; the model's real
responses should normally override these when JSON is valid.
"""
return {
"voiceover": f"Introduce the idea for the '{beat_title}' part in a clear, simple line.",
"on_screen": f"{beat_title} on screen.",
"shots": [
f"Shot of the main subject related to {beat_title.lower()}.",
"Close-up shot for extra detail.",
"Wide shot to show context or environment.",
],
"broll": [
"Supporting b-roll that reinforces the message.",
"Cutaway showing product or user in action.",
],
"captions": [
f"{beat_title} caption text.",
],
}