Skip to content

Instantly share code, notes, and snippets.

@lamviechappy
Last active May 13, 2025 14:14
Show Gist options
  • Save lamviechappy/4c25269bc9531215e54c1da0f4cb3ad4 to your computer and use it in GitHub Desktop.
Save lamviechappy/4c25269bc9531215e54c1da0f4cb3ad4 to your computer and use it in GitHub Desktop.
Streamlit app to rewrite video scripts using OpenAI, Claude, DeepSeek
# 🔹 Phần 1/3 — Khởi tạo, dotenv, UI cơ bản
import streamlit as st
import os
import textwrap
from dotenv import load_dotenv
from datetime import datetime
import openai
import anthropic
import httpx
# Load environment variables
load_dotenv()
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
ANTHROPIC_API_KEY = os.getenv("ANTHROPIC_API_KEY")
DEEPSEEK_API_KEY = os.getenv("DEEPSEEK_API_KEY")
# Session management
if "generated_prompt" not in st.session_state:
st.session_state["generated_prompt"] = ""
if "final_script" not in st.session_state:
st.session_state["final_script"] = ""
if "custom_prompt" not in st.session_state:
st.session_state["custom_prompt"] = ""
if "use_custom_prompt" not in st.session_state:
st.session_state["use_custom_prompt"] = False
# Title
st.title("🎬 AI Video Script Rewriter")
# Input: Old script
old_script = st.text_area("📜 Enter your old video script:", height=200)
# Preset templates
preset_templates = {
"None": {},
"YouTube - Educational": {
"tone": "Informative and friendly",
"sentence_length": "Short to medium",
"use_questions": "Yes",
"vocabulary_level": "Intermediate",
"hook_style": "Bold statement or intriguing question",
"cta_strength": "Moderate, toward end",
},
"YouTube - Motivational": {
"tone": "Inspirational and emotional",
"emotional_tone": "High",
"sentence_length": "Short and punchy",
"use_humor": "Optional",
"cta_strength": "Strong",
"ending_style": "Call to greatness",
},
}
preset = st.selectbox("🎨 Choose a preset style (optional):", options=list(preset_templates.keys()))
preset_data = preset_templates.get(preset, {})
st.markdown("---")
# 🔹 Phần 2/3 — Cấu hình phần tử kịch bản và tạo Prompt
# Collapsible section for script elements
with st.expander("🛠️ Script Elements Configuration", expanded=True):
col1, col2 = st.columns(2)
def checkbox_text_input(col, label, key, default=""):
checked = col.checkbox(f"Enable {label}", key=f"{key}_enabled")
value = col.text_input(f"{label}:", value=preset_data.get(key, default), key=key) if checked else ""
return value if checked else None
# Column 1
tone = checkbox_text_input(col1, "Tone", "tone")
sentence_length = checkbox_text_input(col1, "Sentence and Paragraph Length", "sentence_length")
sentence_variety = checkbox_text_input(col1, "Sentence Variety", "sentence_variety")
level_of_detail = checkbox_text_input(col1, "Level of Detail", "level_of_detail")
use_humor = checkbox_text_input(col1, "Use of Humor", "use_humor")
use_questions = checkbox_text_input(col1, "Use of Questions", "use_questions")
readability = checkbox_text_input(col1, "Readability Level", "readability")
vocabulary_level = checkbox_text_input(col1, "Vocabulary Level", "vocabulary_level")
# Column 2
emotional_tone = checkbox_text_input(col2, "Emotional Tone", "emotional_tone")
target_audience = checkbox_text_input(col2, "Target Audience", "target_audience")
pacing = checkbox_text_input(col2, "Pacing & Rhythm", "pacing")
pov = checkbox_text_input(col2, "Point of View", "pov")
cta_strength = checkbox_text_input(col2, "Call-to-action Strength", "cta_strength")
storytelling_style = checkbox_text_input(col2, "Storytelling Style", "storytelling_style")
visual_descriptiveness = checkbox_text_input(col2, "Visual Imagery", "visual_descriptiveness")
transition_style = checkbox_text_input(col2, "Transitions", "transition_style")
hook_style = checkbox_text_input(col2, "Hook Style", "hook_style")
ending_style = checkbox_text_input(col2, "Ending Style", "ending_style")
additional_notes = checkbox_text_input(col2, "Additional Notes", "additional_notes")
# Generate Prompt Button
if st.button("📝 Generate Prompt"):
prompt = f"Rewrite this video script:\n\n{old_script}\n\ninto a new version with the following adjustments:\n"
def add_if(label, value):
return f"- {label}: {value}\n" if value else ""
prompt += "".join([
add_if("Tone", tone),
add_if("Sentence and Paragraph Length", sentence_length),
add_if("Sentence Variety", sentence_variety),
add_if("Level of Detail", level_of_detail),
add_if("Use of Humor", use_humor),
add_if("Use of Questions", use_questions),
add_if("Readability Level", readability),
add_if("Vocabulary Level", vocabulary_level),
add_if("Emotional Tone", emotional_tone),
add_if("Target Audience", target_audience),
add_if("Pacing & Rhythm", pacing),
add_if("Point of view", pov),
add_if("Call-to-action strength", cta_strength),
add_if("Storytelling style", storytelling_style),
add_if("Visual imagery", visual_descriptiveness),
add_if("Transitions", transition_style),
add_if("Hook style", hook_style),
add_if("Ending style", ending_style),
add_if("Additional notes", additional_notes),
])
st.session_state.generated_prompt = prompt
st.session_state.custom_prompt = prompt
st.session_state.use_custom_prompt = False
# 🔹 Phần 3/3 — Cấu hình AI, tạo script với API, hiển thị & xuất file
st.markdown("---")
st.markdown("### 🤖 AI Model Configuration")
col_a, col_b = st.columns(2)
with col_a:
platform = st.selectbox("Platform", ["OpenAI", "Claude", "DeepSeek"])
model = st.text_input("Model Name", value="gpt-4o" if platform == "OpenAI" else "claude-3-opus-20240229")
temperature = st.slider("Temperature", 0.0, 1.5, 0.7)
with col_b:
max_tokens = st.number_input("Prompt Max Tokens", min_value=100, value=3000)
max_completion_tokens = st.number_input("Max Output Tokens", min_value=100, value=2048)
top_p = st.slider("Top-p (nucleus sampling)", 0.1, 1.0, 1.0)
# Allow prompt editing
st.markdown("### ✏️ Review & Edit Prompt")
prompt_editor = st.text_area("Prompt to send to AI", value=st.session_state.custom_prompt, height=300)
copy_col, edit_col = st.columns(2)
with copy_col:
st.code(prompt_editor, language="markdown")
with edit_col:
if st.button("Apply Edited Prompt"):
st.session_state.custom_prompt = prompt_editor
st.session_state.use_custom_prompt = True
# AI GENERATION
if st.button("🚀 Generate Script with AI"):
final_prompt = st.session_state.custom_prompt if st.session_state.use_custom_prompt else st.session_state.generated_prompt
headers = {"Content-Type": "application/json"}
try:
if platform == "OpenAI":
client = openai.OpenAI(api_key=OPENAI_API_KEY)
response = client.chat.completions.create(
model=model,
messages=[
{"role": "system", "content": "You are a helpful assistant that rewrites video scripts."},
{"role": "user", "content": final_prompt}
],
temperature=temperature,
top_p=top_p,
max_tokens=max_completion_tokens,
)
script = response.choices[0].message.content.strip()
elif platform == "Claude":
client = anthropic.Anthropic(api_key=ANTHROPIC_API_KEY)
response = client.messages.create(
model=model,
max_tokens=max_completion_tokens,
temperature=temperature,
top_p=top_p,
system="You are a creative and helpful assistant that rewrites scripts clearly.",
messages=[{"role": "user", "content": final_prompt}]
)
script = response.content[0].text.strip()
elif platform == "DeepSeek":
headers["Authorization"] = f"Bearer {DEEPSEEK_API_KEY}"
url = "https://api.deepseek.com/chat/completions"
payload = {
"model": model,
"messages": [
{"role": "system", "content": "You are a helpful assistant that rewrites video scripts."},
{"role": "user", "content": final_prompt}
],
"temperature": temperature,
"top_p": top_p,
"max_tokens": max_completion_tokens,
}
with httpx.Client() as client:
resp = client.post(url, json=payload, headers=headers, timeout=30)
script = resp.json()["choices"][0]["message"]["content"].strip()
st.session_state.final_script = script
except Exception as e:
st.error(f"Error generating script: {e}")
# Show generated script
if st.session_state.final_script:
st.markdown("### 🧾 Rewritten Script")
st.text_area("AI-Generated Script", value=st.session_state.final_script, height=400)
now = datetime.now().strftime("%Y%m%d_%H%M%S")
prompt_filename_md = f"generated_prompt_{now}.md"
script_filename_md = f"rewritten_script_{now}.md"
prompt_filename_txt = f"generated_prompt_{now}.txt"
script_filename_txt = f"rewritten_script_{now}.txt"
st.download_button("⬇️ Download Prompt (.txt)", st.session_state.custom_prompt, file_name=prompt_filename_txt)
st.download_button("⬇️ Download Prompt (.md)", st.session_state.custom_prompt, file_name=prompt_filename_md)
st.download_button("⬇️ Download Script (.txt)", st.session_state.final_script, file_name=script_filename_txt)
st.download_button("⬇️ Download Script (.md)", st.session_state.final_script, file_name=script_filename_md)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment