devendergarg14 commited on
Commit
eb2b92e
·
verified ·
1 Parent(s): a995631

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +25 -18
app.py CHANGED
@@ -14,9 +14,9 @@ def modify_animation_times(code: str, factor: float = 1.0, for_precheck: bool =
14
  Modifies wait() and run_time in the code.
15
 
16
  1. If for_precheck=True:
17
- - Sets all self.wait(...) to self.wait(0).
18
- - Sets all run_time=... to run_time=0.
19
- - This makes heavy simulation loops execute instantly during the 'manim -s' check.
20
 
21
  2. If for_precheck=False (Preview Mode):
22
  - Scales animation speed by 'factor'.
@@ -27,10 +27,9 @@ def modify_animation_times(code: str, factor: float = 1.0, for_precheck: bool =
27
  if for_precheck:
28
  print("⚡ Optimizing code for Pre-check (Zero Latency)...", flush=True)
29
  # Regex: Find self.wait(ANYTHING) and replace with self.wait(0)
30
- # We use [^)]* to match any content inside the parenthesis (numbers, math, variables)
31
  code = re.sub(r"self\.wait\s*\([^)]*\)", "self.wait(0)", code)
32
 
33
- # Regex: Find run_time=ANYTHING (until a comma or parenthesis) and set to 0.01
34
  code = re.sub(r"run_time\s*=\s*[^,)]+", "run_time=0.01", code)
35
  return code
36
 
@@ -59,16 +58,20 @@ def modify_animation_times(code: str, factor: float = 1.0, for_precheck: bool =
59
 
60
  def run_manim_pre_check(code_str: str) -> (bool, str):
61
  """
62
- Runs Manim with the '-s' flag to perform a fast, reliable pre-check.
63
- Uses the 'Speed Hack' (modify_animation_times) to ensure heavy loops
64
- don't cause a timeout.
 
 
 
 
65
  """
66
  print("🕵️ Running fast pre-check with 'manim -s'...", flush=True)
67
 
68
- # Apply the speed hack: waits become 0s
69
  fast_code = modify_animation_times(code_str, for_precheck=True)
70
 
71
- # Write the modified code to a temporary file
72
  with open("scene_pre_check.py", "w", encoding="utf-8") as f:
73
  f.write(fast_code)
74
 
@@ -78,26 +81,27 @@ def run_manim_pre_check(code_str: str) -> (bool, str):
78
  "--progress_bar", "none",
79
  "--disable_caching",
80
  "scene_pre_check.py", "GenScene",
81
- "-s", # Save last frame only (no video encoding)
82
  "-o", "pre_check_output"
83
  ]
84
 
85
  try:
86
- # 30s is now plenty of time because we removed all waits
87
  process = subprocess.run(cmd, capture_output=True, timeout=30, check=False)
88
 
89
  if process.returncode == 0:
90
  print("✅ Pre-check passed. Code is valid.", flush=True)
91
  return True, "Pre-check successful."
92
  else:
 
93
  stderr_log = process.stderr.decode('utf-8', 'ignore')
94
  print(f"❌ Pre-check failed.\n{stderr_log}", flush=True)
95
  return False, f"⚠️ ERROR: Your code failed the pre-check.\n\n--- ERROR LOG ---\n{stderr_log}"
96
 
97
  except subprocess.TimeoutExpired:
98
- print("⌛ Pre-check timed out.", flush=True)
99
- # Even with the speed hack, if it times out, it's likely a true infinite loop (while True)
100
- return False, " ERROR: The pre-check timed out. The code likely contains an infinite loop."
101
 
102
  def cleanup_media_directory():
103
  """Wipes the media directory to prevent caching issues."""
@@ -164,17 +168,20 @@ def run_manim(code_str, orientation, quality, timeout):
164
  def render_video_from_code(code, orientation, quality, timeout, preview_factor):
165
  """Renders a video from a given Manim code string."""
166
  try:
167
- # --- 1. Pre-Check (With Speed Hack) ---
168
  is_valid, logs = run_manim_pre_check(code)
 
 
169
  if not is_valid:
170
  return None, logs, gr.Button(visible=True)
171
 
 
 
172
  cleanup_media_directory()
173
  if not code or "from manim import" not in code:
174
  return None, "Error: No valid code to render.", gr.Button(visible=False)
175
 
176
- # --- 2. Prepare Code for Render ---
177
- # If quality is Preview, we scale time. If not, we use original code.
178
  if quality == "Preview (360p)":
179
  code_to_render = modify_animation_times(code, factor=float(preview_factor) or 0.5, for_precheck=False)
180
  else:
 
14
  Modifies wait() and run_time in the code.
15
 
16
  1. If for_precheck=True:
17
+ - Sets self.wait(...) to self.wait(0).
18
+ - Sets run_time=... to run_time=0.01.
19
+ - This attempts to make the validation run instantly.
20
 
21
  2. If for_precheck=False (Preview Mode):
22
  - Scales animation speed by 'factor'.
 
27
  if for_precheck:
28
  print("⚡ Optimizing code for Pre-check (Zero Latency)...", flush=True)
29
  # Regex: Find self.wait(ANYTHING) and replace with self.wait(0)
 
30
  code = re.sub(r"self\.wait\s*\([^)]*\)", "self.wait(0)", code)
31
 
32
+ # Regex: Find run_time=ANYTHING and set to 0.01 to avoid "run_time <= 0" error
33
  code = re.sub(r"run_time\s*=\s*[^,)]+", "run_time=0.01", code)
34
  return code
35
 
 
58
 
59
  def run_manim_pre_check(code_str: str) -> (bool, str):
60
  """
61
+ Runs Manim with the '-s' flag to perform a fast pre-check.
62
+
63
+ CRITICAL BEHAVIOR:
64
+ 1. Tries to run quickly using 'modify_animation_times'.
65
+ 2. If it catches a SyntaxError or NameError, it FAILS (Returns False).
66
+ 3. If it runs for >30 seconds (Timeout), it PASSES (Returns True), assuming
67
+ the code is valid but just computationally heavy.
68
  """
69
  print("🕵️ Running fast pre-check with 'manim -s'...", flush=True)
70
 
71
+ # Apply the speed hack
72
  fast_code = modify_animation_times(code_str, for_precheck=True)
73
 
74
+ # Write to temp file
75
  with open("scene_pre_check.py", "w", encoding="utf-8") as f:
76
  f.write(fast_code)
77
 
 
81
  "--progress_bar", "none",
82
  "--disable_caching",
83
  "scene_pre_check.py", "GenScene",
84
+ "-s", # Save last frame only
85
  "-o", "pre_check_output"
86
  ]
87
 
88
  try:
89
+ # Run for max 30 seconds
90
  process = subprocess.run(cmd, capture_output=True, timeout=30, check=False)
91
 
92
  if process.returncode == 0:
93
  print("✅ Pre-check passed. Code is valid.", flush=True)
94
  return True, "Pre-check successful."
95
  else:
96
+ # Code finished but failed (e.g. Syntax Error)
97
  stderr_log = process.stderr.decode('utf-8', 'ignore')
98
  print(f"❌ Pre-check failed.\n{stderr_log}", flush=True)
99
  return False, f"⚠️ ERROR: Your code failed the pre-check.\n\n--- ERROR LOG ---\n{stderr_log}"
100
 
101
  except subprocess.TimeoutExpired:
102
+ # Code ran for 30s without crashing. likely valid but heavy.
103
+ print("⌛ Pre-check timed out (30s). Assuming code is valid but heavy.", flush=True)
104
+ return True, "⚠️ Warning: Pre-check timed out (30s). The code seems valid but is very heavy. Proceeding to full render..."
105
 
106
  def cleanup_media_directory():
107
  """Wipes the media directory to prevent caching issues."""
 
168
  def render_video_from_code(code, orientation, quality, timeout, preview_factor):
169
  """Renders a video from a given Manim code string."""
170
  try:
171
+ # --- 1. Pre-Check (With Speed Hack & Soft Pass) ---
172
  is_valid, logs = run_manim_pre_check(code)
173
+
174
+ # If is_valid is False, it means there was a real Error (Syntax, NameError, etc.)
175
  if not is_valid:
176
  return None, logs, gr.Button(visible=True)
177
 
178
+ # If is_valid is True, we proceed (even if it timed out)
179
+
180
  cleanup_media_directory()
181
  if not code or "from manim import" not in code:
182
  return None, "Error: No valid code to render.", gr.Button(visible=False)
183
 
184
+ # --- 2. Prepare Code for Real Render ---
 
185
  if quality == "Preview (360p)":
186
  code_to_render = modify_animation_times(code, factor=float(preview_factor) or 0.5, for_precheck=False)
187
  else: