rairo commited on
Commit
e1f21b7
·
verified ·
1 Parent(s): cd5b6c2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +9 -12
app.py CHANGED
@@ -1,12 +1,11 @@
1
  ##############################################################################
2
  # Sozo Business Studio · 10-Jul-2025
3
- # • FIXED: Animation and FFmpeg errors while preserving the user's AI architecture.
4
- # • FIXED: The 'can't multiply sequence' error by replacing the animation engine.
5
- # • FIXED: FFmpeg failures with a robust media concatenation function.
6
  # • NOTE: The user's prompts, classes, and AI calls are preserved exactly.
7
  ##############################################################################
8
 
9
- import os, re, json, hashlib, uuid, base64, io, tempfile, requests, subprocess
10
  from pathlib import Path
11
  from typing import Tuple, Dict, List
12
 
@@ -182,7 +181,6 @@ class ChartGenerator:
182
  if response.startswith("```json"): response = response[7:-3]
183
  elif response.startswith("```"): response = response[3:-3]
184
  spec_dict = json.loads(response)
185
- # Filter to only include keys expected by the ChartSpecification constructor
186
  valid_keys = [p.name for p in inspect.signature(ChartSpecification).parameters.values()]
187
  filtered_dict = {k: v for k, v in spec_dict.items() if k in valid_keys}
188
  return ChartSpecification(**filtered_dict)
@@ -194,7 +192,7 @@ class ChartGenerator:
194
  numeric_cols = self.enhanced_ctx['numeric_columns']; categorical_cols = self.enhanced_ctx['categorical_columns']
195
  if "bar" in description.lower() and categorical_cols and numeric_cols: return ChartSpecification("bar", description, categorical_cols[0], numeric_cols[0])
196
  elif "pie" in description.lower() and categorical_cols and numeric_cols: return ChartSpecification("pie", description, categorical_cols[0], numeric_cols[0])
197
- elif "line" in description.lower() and len(numeric_cols) >= 1: return ChartSpecification("line", description, self.df.columns[0], numeric_cols[0])
198
  elif "scatter" in description.lower() and len(numeric_cols) >= 2: return ChartSpecification("scatter", description, numeric_cols[0], numeric_cols[1])
199
  elif "hist" in description.lower() and numeric_cols: return ChartSpecification("hist", description, numeric_cols[0], None)
200
  else: return ChartSpecification("bar", description, self.df.columns[0], self.df.columns[1] if len(self.df.columns) > 1 else None)
@@ -229,14 +227,14 @@ def animate_chart(spec: ChartSpecification, df: pd.DataFrame, dur: float, out: P
229
  """FIXED: Renders a reliable animated chart using proven patterns, compatible with ChartSpecification."""
230
  plot_data = prepare_plot_data(spec, df)
231
  title = spec.title
232
- frames = max(10, int(dur * fps)) # Ensure integer frame count
233
  fig, ax = plt.subplots(figsize=(WIDTH / 100, HEIGHT / 100), dpi=100)
234
  plt.tight_layout(pad=2.5)
235
  ctype = spec.chart_type
236
 
237
- # This robust animation logic is adapted from the working example
238
  if ctype == "pie":
239
- wedges, _ = ax.pie(plot_data, labels=plot_data.index, startangle=90, autopct='%1.1f%%')
 
240
  ax.set_title(title); ax.axis('equal')
241
  def init(): [w.set_alpha(0) for w in wedges]; return wedges
242
  def update(i): [w.set_alpha(i / (frames - 1)) for w in wedges]; return wedges
@@ -249,7 +247,7 @@ def animate_chart(spec: ChartSpecification, df: pd.DataFrame, dur: float, out: P
249
  progress = i / (frames - 1)
250
  for b, h in zip(bars, plot_data.values): b.set_height(h * progress)
251
  return bars
252
- else: # line, scatter, hist
253
  line, = ax.plot([], [], lw=2)
254
  if ctype == 'scatter':
255
  x_full, y_full = plot_data.iloc[:, 0], plot_data.iloc[:, 1]
@@ -287,7 +285,6 @@ def safe_chart(desc: str, df: pd.DataFrame, dur: float, out: Path) -> str:
287
  return animate_chart(chart_spec, df, dur, out)
288
  except Exception as e:
289
  print(f"Chart animation failed for '{desc}': {e}. Falling back to static image.")
290
- # Fallback: create a static version of the chart and fade it in
291
  temp_png = out.with_suffix(".png")
292
  llm = ChatGoogleGenerativeAI(model="gemini-2.0-flash", google_api_key=API_KEY, temperature=0.1)
293
  chart_generator = create_chart_generator(llm, df)
@@ -296,7 +293,7 @@ def safe_chart(desc: str, df: pd.DataFrame, dur: float, out: Path) -> str:
296
  img = cv2.imread(str(temp_png))
297
  img_resized = cv2.resize(img, (WIDTH, HEIGHT))
298
  return animate_image_fade(img_resized, dur, out)
299
- else: # Ultimate fallback
300
  img = generate_image_from_prompt(f"A professional business chart showing {desc}")
301
  img_cv = cv2.cvtColor(np.array(img.resize((WIDTH, HEIGHT))), cv2.COLOR_RGB2BGR)
302
  return animate_image_fade(img_cv, dur, out)
 
1
  ##############################################################################
2
  # Sozo Business Studio · 10-Jul-2025
3
+ # • FIXED: Added missing 'inspect' import to resolve NameError in ChartGenerator.
4
+ # • FIXED: Corrected tuple unpacking for pie charts in the animation function.
 
5
  # • NOTE: The user's prompts, classes, and AI calls are preserved exactly.
6
  ##############################################################################
7
 
8
+ import os, re, json, hashlib, uuid, base64, io, tempfile, requests, subprocess, inspect # FIXED: Added missing import
9
  from pathlib import Path
10
  from typing import Tuple, Dict, List
11
 
 
181
  if response.startswith("```json"): response = response[7:-3]
182
  elif response.startswith("```"): response = response[3:-3]
183
  spec_dict = json.loads(response)
 
184
  valid_keys = [p.name for p in inspect.signature(ChartSpecification).parameters.values()]
185
  filtered_dict = {k: v for k, v in spec_dict.items() if k in valid_keys}
186
  return ChartSpecification(**filtered_dict)
 
192
  numeric_cols = self.enhanced_ctx['numeric_columns']; categorical_cols = self.enhanced_ctx['categorical_columns']
193
  if "bar" in description.lower() and categorical_cols and numeric_cols: return ChartSpecification("bar", description, categorical_cols[0], numeric_cols[0])
194
  elif "pie" in description.lower() and categorical_cols and numeric_cols: return ChartSpecification("pie", description, categorical_cols[0], numeric_cols[0])
195
+ elif "line" in description.lower() and len(numeric_cols) >= 1: return ChartSpecification("line", self.df.columns[0], numeric_cols[0])
196
  elif "scatter" in description.lower() and len(numeric_cols) >= 2: return ChartSpecification("scatter", description, numeric_cols[0], numeric_cols[1])
197
  elif "hist" in description.lower() and numeric_cols: return ChartSpecification("hist", description, numeric_cols[0], None)
198
  else: return ChartSpecification("bar", description, self.df.columns[0], self.df.columns[1] if len(self.df.columns) > 1 else None)
 
227
  """FIXED: Renders a reliable animated chart using proven patterns, compatible with ChartSpecification."""
228
  plot_data = prepare_plot_data(spec, df)
229
  title = spec.title
230
+ frames = max(10, int(dur * fps))
231
  fig, ax = plt.subplots(figsize=(WIDTH / 100, HEIGHT / 100), dpi=100)
232
  plt.tight_layout(pad=2.5)
233
  ctype = spec.chart_type
234
 
 
235
  if ctype == "pie":
236
+ # FIXED: Correctly unpack the three return values from ax.pie when autopct is used
237
+ wedges, _, _ = ax.pie(plot_data, labels=plot_data.index, startangle=90, autopct='%1.1f%%')
238
  ax.set_title(title); ax.axis('equal')
239
  def init(): [w.set_alpha(0) for w in wedges]; return wedges
240
  def update(i): [w.set_alpha(i / (frames - 1)) for w in wedges]; return wedges
 
247
  progress = i / (frames - 1)
248
  for b, h in zip(bars, plot_data.values): b.set_height(h * progress)
249
  return bars
250
+ else:
251
  line, = ax.plot([], [], lw=2)
252
  if ctype == 'scatter':
253
  x_full, y_full = plot_data.iloc[:, 0], plot_data.iloc[:, 1]
 
285
  return animate_chart(chart_spec, df, dur, out)
286
  except Exception as e:
287
  print(f"Chart animation failed for '{desc}': {e}. Falling back to static image.")
 
288
  temp_png = out.with_suffix(".png")
289
  llm = ChatGoogleGenerativeAI(model="gemini-2.0-flash", google_api_key=API_KEY, temperature=0.1)
290
  chart_generator = create_chart_generator(llm, df)
 
293
  img = cv2.imread(str(temp_png))
294
  img_resized = cv2.resize(img, (WIDTH, HEIGHT))
295
  return animate_image_fade(img_resized, dur, out)
296
+ else:
297
  img = generate_image_from_prompt(f"A professional business chart showing {desc}")
298
  img_cv = cv2.cvtColor(np.array(img.resize((WIDTH, HEIGHT))), cv2.COLOR_RGB2BGR)
299
  return animate_image_fade(img_cv, dur, out)