theminji commited on
Commit
1c0a656
·
verified ·
1 Parent(s): 0f3297f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +29 -26
app.py CHANGED
@@ -7,6 +7,7 @@ import shutil
7
  import time
8
  from threading import Timer
9
  import uuid
 
10
 
11
  app = Flask(__name__)
12
 
@@ -16,6 +17,10 @@ if not API_KEY:
16
  raise ValueError("Missing GOOGLE_API_KEY environment variable.")
17
  client = genai.Client(api_key=API_KEY)
18
 
 
 
 
 
19
  @app.route("/", methods=["GET", "POST"])
20
  def index():
21
  if request.method == "POST":
@@ -25,9 +30,11 @@ def index():
25
 
26
  max_retries = 3
27
  attempt = 0
 
28
  while attempt < max_retries:
29
  try:
30
- # Call the GenAI API to get the Manim code
 
31
  ai_response = client.models.generate_content(
32
  model="gemini-2.0-flash-lite-preview-02-05",
33
  contents=f"""You are 'Manimator', an expert Manim animator and coder.
@@ -47,6 +54,8 @@ You got this!! <3
47
  if not match:
48
  raise Exception("No python code block found in the AI response.")
49
  code = match.group(1)
 
 
50
 
51
  # Determine the scene class name from the generated code
52
  scene_match = re.search(r"class\s+(\w+)\(.*Scene.*\):", code)
@@ -63,11 +72,7 @@ You got this!! <3
63
  with open(code_filename, "w") as f:
64
  f.write(code)
65
 
66
- # Set a dedicated media directory for Manim output in /tmp
67
- media_dir = os.path.join("/tmp", "manim_media")
68
- os.makedirs(media_dir, exist_ok=True)
69
-
70
- # Prepare the Manim command with the --media_dir flag
71
  cmd = [
72
  "manim",
73
  "-qm",
@@ -76,29 +81,27 @@ You got this!! <3
76
  code_filename,
77
  scene_name
78
  ]
79
- # Run Manim to generate the video, capturing its output
 
80
  result = subprocess.run(cmd, check=True, capture_output=True, text=True)
81
  print("Manim stdout:", result.stdout)
82
  print("Manim stderr:", result.stderr)
 
 
 
 
 
 
83
 
84
  # Construct the expected output path from Manim.
85
- # With --media_dir set, Manim should write the video to:
86
- # {media_dir}/videos/<code_filename_without_.py>/720p30/<video_filename>
87
- video_path_in_media = os.path.join(
88
- media_dir,
89
- "videos",
90
- code_filename.replace(".py", ""),
91
- "720p30",
92
- video_filename
93
- )
94
- # Verify that Manim produced the expected video file
95
  if not os.path.exists(video_path_in_media):
96
- raise Exception("Manim did not produce the expected output file.")
97
 
98
- # Move both the video and the generated code file to /tmp (a writable location)
99
  tmp_video_path = os.path.join("/tmp", video_filename)
100
  shutil.move(video_path_in_media, tmp_video_path)
101
-
102
  tmp_code_path = os.path.join("/tmp", code_filename)
103
  shutil.move(code_filename, tmp_code_path)
104
 
@@ -110,27 +113,27 @@ You got this!! <3
110
  if os.path.exists(tmp_code_path):
111
  os.remove(tmp_code_path)
112
  print("Removed files:", tmp_video_path, tmp_code_path)
 
113
  except Exception as e:
114
  app.logger.error("Error removing files: %s", e)
115
  Timer(600, remove_files).start()
116
 
117
- # Generate a URL that points to our video-serving route (the video file is in /tmp)
118
  video_url = url_for('get_video', filename=video_filename)
119
  return render_template("result.html", video_url=video_url)
120
 
121
  except Exception as e:
122
- print(f"Attempt {attempt + 1} failed: {e}")
 
 
123
  attempt += 1
124
- time.sleep(1) # Wait a bit before retrying
125
 
126
- # If we reach here, we've exceeded the maximum number of retries.
127
- return render_template("result.html", error="An error occurred. Please try again later.")
128
 
129
  return render_template("index.html")
130
 
131
  @app.route("/video/<filename>")
132
  def get_video(filename):
133
- # Serve the video file from /tmp
134
  return send_from_directory("/tmp", filename)
135
 
136
  if __name__ == "__main__":
 
7
  import time
8
  from threading import Timer
9
  import uuid
10
+ import sys
11
 
12
  app = Flask(__name__)
13
 
 
17
  raise ValueError("Missing GOOGLE_API_KEY environment variable.")
18
  client = genai.Client(api_key=API_KEY)
19
 
20
+ # Define a dedicated media directory in /tmp
21
+ media_dir = os.path.join("/tmp", "manim_media")
22
+ os.makedirs(media_dir, exist_ok=True)
23
+
24
  @app.route("/", methods=["GET", "POST"])
25
  def index():
26
  if request.method == "POST":
 
30
 
31
  max_retries = 3
32
  attempt = 0
33
+ last_error = None
34
  while attempt < max_retries:
35
  try:
36
+ print("Calling GenAI API...")
37
+ sys.stdout.flush()
38
  ai_response = client.models.generate_content(
39
  model="gemini-2.0-flash-lite-preview-02-05",
40
  contents=f"""You are 'Manimator', an expert Manim animator and coder.
 
54
  if not match:
55
  raise Exception("No python code block found in the AI response.")
56
  code = match.group(1)
57
+ print("Extracted code (first 200 chars):", code[:200])
58
+ sys.stdout.flush()
59
 
60
  # Determine the scene class name from the generated code
61
  scene_match = re.search(r"class\s+(\w+)\(.*Scene.*\):", code)
 
72
  with open(code_filename, "w") as f:
73
  f.write(code)
74
 
75
+ # Prepare the Manim command with --media_dir flag
 
 
 
 
76
  cmd = [
77
  "manim",
78
  "-qm",
 
81
  code_filename,
82
  scene_name
83
  ]
84
+ print("Running Manim command:", " ".join(cmd))
85
+ sys.stdout.flush()
86
  result = subprocess.run(cmd, check=True, capture_output=True, text=True)
87
  print("Manim stdout:", result.stdout)
88
  print("Manim stderr:", result.stderr)
89
+ sys.stdout.flush()
90
+
91
+ # Debug: list the media directory structure
92
+ for root, dirs, files in os.walk(media_dir):
93
+ print(root, dirs, files)
94
+ sys.stdout.flush()
95
 
96
  # Construct the expected output path from Manim.
97
+ expected_dir = os.path.join(media_dir, "videos", code_filename.replace(".py", ""), "720p30")
98
+ video_path_in_media = os.path.join(expected_dir, video_filename)
 
 
 
 
 
 
 
 
99
  if not os.path.exists(video_path_in_media):
100
+ raise Exception(f"Manim did not produce the expected output file at {video_path_in_media}")
101
 
102
+ # Move both the video and the generated code file to /tmp
103
  tmp_video_path = os.path.join("/tmp", video_filename)
104
  shutil.move(video_path_in_media, tmp_video_path)
 
105
  tmp_code_path = os.path.join("/tmp", code_filename)
106
  shutil.move(code_filename, tmp_code_path)
107
 
 
113
  if os.path.exists(tmp_code_path):
114
  os.remove(tmp_code_path)
115
  print("Removed files:", tmp_video_path, tmp_code_path)
116
+ sys.stdout.flush()
117
  except Exception as e:
118
  app.logger.error("Error removing files: %s", e)
119
  Timer(600, remove_files).start()
120
 
 
121
  video_url = url_for('get_video', filename=video_filename)
122
  return render_template("result.html", video_url=video_url)
123
 
124
  except Exception as e:
125
+ print(f"Attempt {attempt + 1} failed: {type(e).__name__}: {e}")
126
+ sys.stdout.flush()
127
+ last_error = e
128
  attempt += 1
129
+ time.sleep(1)
130
 
131
+ return render_template("result.html", error=f"Error: {last_error}")
 
132
 
133
  return render_template("index.html")
134
 
135
  @app.route("/video/<filename>")
136
  def get_video(filename):
 
137
  return send_from_directory("/tmp", filename)
138
 
139
  if __name__ == "__main__":