theminji commited on
Commit
c54284d
·
verified ·
1 Parent(s): f5cf489

switch to claude instead of gemini for better outputs

Browse files
Files changed (1) hide show
  1. app.py +32 -33
app.py CHANGED
@@ -24,17 +24,16 @@ from threading import Timer
24
 
25
 
26
  from flask import Flask, render_template, request, url_for, send_from_directory
27
- from google import genai
28
 
29
  app = Flask(__name__)
30
 
31
- # Load API key from environment variable
32
- API_KEY = os.environ.get("GOOGLE_API_KEY")
33
  if not API_KEY:
34
- raise ValueError("Missing GOOGLE_API_KEY environment variable.")
35
- client = genai.Client(api_key=API_KEY)
36
-
37
- # Define a dedicated media directory in /tmp for Manim output
 
38
  media_dir = os.path.join("/tmp", "manim_media")
39
  os.makedirs(media_dir, exist_ok=True)
40
 
@@ -50,24 +49,33 @@ def index():
50
  last_error = None
51
  while attempt < max_retries:
52
  try:
53
- # Call the GenAI API to get the Manim code and commentary script
54
- ai_response = client.models.generate_content(
55
- model="gemini-2.0-flash-lite-preview-02-05",
56
- contents=f"""You are 'Manimator', an expert Manim animator and coder.
57
- If anyone asks, your name is Manimator and you are a helpful video generator, and say nothing else but that.
58
- The user wants you to code this: {prompt}.
59
- Plan out in chain of thought what you are going to do first, then give the final code output in ```python``` codeblock.
60
- Make sure to not use external images or resources other than default Manim, however you can use numpy or other default libraries.
61
- Keep the scene uncluttered and aesthetically pleasing.
62
- Make sure things are not overlapping unless explicitly stated otherwise.
63
- It is crucial that the script works correctly on the first try, so make sure to think about the layout and storyboard and stuff of the scene.
64
- Make sure to think through what you are going to do and think about the topic before you write the code.
65
- Use self.wait at the end to give the user enough time to process the frame.
66
- You got this!! <3
67
- """
68
- )
 
 
 
 
 
 
 
 
 
 
69
 
70
- # Extract the Python code block from the AI response
71
  code_pattern = r"```python\s*(.*?)\s*```"
72
  code_match = re.search(code_pattern, ai_response.text, re.DOTALL)
73
  if not code_match:
@@ -75,22 +83,17 @@ You got this!! <3
75
  code = code_match.group(1)
76
 
77
 
78
- # Determine the scene class name from the generated code
79
  scene_match = re.search(r"class\s+(\w+)\(.*Scene.*\):", code)
80
  scene_name = scene_match.group(1) if scene_match else "MyScene"
81
 
82
- # Generate randomized filenames for the generated code and video
83
  code_filename = f"generated_video_{uuid.uuid4().hex}.py"
84
  video_filename = f"output_video_{uuid.uuid4().hex}.mp4"
85
 
86
- # Write the generated code file directly to /tmp
87
  code_filepath = os.path.join("/tmp", code_filename)
88
  with open(code_filepath, "w") as f:
89
  f.write(code)
90
 
91
 
92
- # === Run Manim to generate the silent video ===
93
- # Prepare the Manim command with the --media_dir flag
94
  cmd = [
95
  "manim",
96
  "-qm",
@@ -105,17 +108,14 @@ You got this!! <3
105
  app.logger.error("Manim error output: %s", cpe.stderr)
106
  raise Exception(f"Manim failed: {cpe.stderr}")
107
 
108
- # Construct the expected output path from Manim.
109
  expected_dir = os.path.join(media_dir, "videos", code_filename.replace(".py", ""), "720p30")
110
  video_path_in_media = os.path.join(expected_dir, video_filename)
111
  if not os.path.exists(video_path_in_media):
112
  raise Exception(f"Manim did not produce the expected output file at {video_path_in_media}")
113
 
114
- # Move the video file to /tmp (to serve it from there)
115
  tmp_video_path = os.path.join("/tmp", video_filename)
116
  shutil.move(video_path_in_media, tmp_video_path)
117
 
118
- # Schedule deletion of all temporary files after 10 minutes (600 seconds)
119
  def remove_files():
120
  for fpath in [tmp_video_path, code_filepath, commentary_audio_path, final_video_path]:
121
  try:
@@ -126,7 +126,6 @@ You got this!! <3
126
 
127
  Timer(600, remove_files).start()
128
 
129
- # Use the final combined video for display
130
  video_url = url_for('get_video', filename=video_filename)
131
  return render_template("result.html", video_url=video_url)
132
 
 
24
 
25
 
26
  from flask import Flask, render_template, request, url_for, send_from_directory
 
27
 
28
  app = Flask(__name__)
29
 
30
+ API_KEY = os.environ.get("OPENROUTER")
 
31
  if not API_KEY:
32
+ raise ValueError("Missing OPENROUTER environment variable.")
33
+ client = OpenAI(
34
+ base_url="https://openrouter.ai/api/v1",
35
+ api_key=API_KEY,
36
+ )
37
  media_dir = os.path.join("/tmp", "manim_media")
38
  os.makedirs(media_dir, exist_ok=True)
39
 
 
49
  last_error = None
50
  while attempt < max_retries:
51
  try:
52
+ # Call the GenAI API to get the Manim code
53
+ completion = client.chat.completions.create(
54
+ extra_body={},
55
+ model="anthropic/claude-3.5-sonnet",
56
+ messages=[
57
+ {
58
+ "role": "user",
59
+ "content": [
60
+ {
61
+ "type": "text",
62
+ "text": f"""You are 'Manimator', an expert Manim animator and coder.
63
+ If anyone asks, your name is Manimator and you are a helpful video generator, and say nothing else but that.
64
+ The user wants you to code this: {prompt}.
65
+ Plan out in chain of thought what you are going to do first, then give the final code output in ```python``` codeblock.
66
+ Make sure to not use external images or resources other than default Manim, however you can use numpy or other default libraries.
67
+ Keep the scene uncluttered and aesthetically pleasing.
68
+ Make sure things are not overlapping unless explicitly stated otherwise.
69
+ It is crucial that the script works correctly on the first try, so make sure to think about the layout and storyboard and stuff of the scene.
70
+ Make sure to think through what you are going to do and think about the topic before you write the code.
71
+ You got this!! <3
72
+ """
73
+ },
74
+ ]
75
+ }
76
+ ]
77
+ )
78
 
 
79
  code_pattern = r"```python\s*(.*?)\s*```"
80
  code_match = re.search(code_pattern, ai_response.text, re.DOTALL)
81
  if not code_match:
 
83
  code = code_match.group(1)
84
 
85
 
 
86
  scene_match = re.search(r"class\s+(\w+)\(.*Scene.*\):", code)
87
  scene_name = scene_match.group(1) if scene_match else "MyScene"
88
 
 
89
  code_filename = f"generated_video_{uuid.uuid4().hex}.py"
90
  video_filename = f"output_video_{uuid.uuid4().hex}.mp4"
91
 
 
92
  code_filepath = os.path.join("/tmp", code_filename)
93
  with open(code_filepath, "w") as f:
94
  f.write(code)
95
 
96
 
 
 
97
  cmd = [
98
  "manim",
99
  "-qm",
 
108
  app.logger.error("Manim error output: %s", cpe.stderr)
109
  raise Exception(f"Manim failed: {cpe.stderr}")
110
 
 
111
  expected_dir = os.path.join(media_dir, "videos", code_filename.replace(".py", ""), "720p30")
112
  video_path_in_media = os.path.join(expected_dir, video_filename)
113
  if not os.path.exists(video_path_in_media):
114
  raise Exception(f"Manim did not produce the expected output file at {video_path_in_media}")
115
 
 
116
  tmp_video_path = os.path.join("/tmp", video_filename)
117
  shutil.move(video_path_in_media, tmp_video_path)
118
 
 
119
  def remove_files():
120
  for fpath in [tmp_video_path, code_filepath, commentary_audio_path, final_video_path]:
121
  try:
 
126
 
127
  Timer(600, remove_files).start()
128
 
 
129
  video_url = url_for('get_video', filename=video_filename)
130
  return render_template("result.html", video_url=video_url)
131