Spaces:
Running
Running
| """ | |
| NeuraPrompt Agent β Media Tools (v9.0) | |
| Charts, QR codes, image manipulation, screenshots β all with download URLs. | |
| Auto-installs required packages if missing. | |
| """ | |
| import os | |
| import uuid | |
| import subprocess | |
| import logging | |
| from pathlib import Path | |
| from typing import List, Dict, Optional, Any | |
| log = logging.getLogger("agent.tools.media") | |
| OUTPUT_DIR = Path("/tmp/agent_outputs") | |
| OUTPUT_DIR.mkdir(parents=True, exist_ok=True) | |
| BASE_URL = os.getenv("SPACE_HOST", "https://deepimagix-self-trained2.hf.space") | |
| def _url(filename: str) -> str: | |
| return f"{BASE_URL}/agent/download/{filename}" | |
| def _install(package: str): | |
| subprocess.run(["pip", "install", package, "--quiet"], capture_output=True) | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # BAR CHART | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def create_bar_chart( | |
| labels: List[str], | |
| values: List[float], | |
| title: str = "Chart", | |
| x_label: str = "", | |
| y_label: str = "", | |
| filename: Optional[str] = None | |
| ) -> str: | |
| """ | |
| Create a bar chart image (PNG). | |
| Args: | |
| labels : List of bar labels | |
| values : List of numeric values | |
| title : Chart title | |
| x_label : X axis label | |
| y_label : Y axis label | |
| filename : Optional output filename | |
| Returns: | |
| str: Download URL for the chart image | |
| """ | |
| try: | |
| import matplotlib | |
| matplotlib.use("Agg") | |
| import matplotlib.pyplot as plt | |
| except ImportError: | |
| _install("matplotlib") | |
| import matplotlib | |
| matplotlib.use("Agg") | |
| import matplotlib.pyplot as plt | |
| try: | |
| fname = filename or f"chart_{uuid.uuid4().hex[:8]}.png" | |
| if not fname.endswith(".png"): | |
| fname += ".png" | |
| out_path = OUTPUT_DIR / fname | |
| fig, ax = plt.subplots(figsize=(10, 6)) | |
| bars = ax.bar(labels, values, color="black", edgecolor="white") | |
| ax.set_title(title, fontsize=16, fontweight="bold") | |
| ax.set_xlabel(x_label, fontsize=12) | |
| ax.set_ylabel(y_label, fontsize=12) | |
| ax.spines["top"].set_visible(False) | |
| ax.spines["right"].set_visible(False) | |
| # Value labels on bars | |
| for bar, val in zip(bars, values): | |
| ax.text( | |
| bar.get_x() + bar.get_width() / 2, | |
| bar.get_height() + max(values) * 0.01, | |
| str(round(val, 2)), | |
| ha="center", va="bottom", fontsize=10 | |
| ) | |
| plt.tight_layout() | |
| plt.savefig(str(out_path), dpi=150, bbox_inches="tight") | |
| plt.close() | |
| return f"β Bar chart created!\nπ₯ Download: {_url(fname)}" | |
| except Exception as e: | |
| return f"Bar chart error: {str(e)}" | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # LINE CHART | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def create_line_chart( | |
| x_values: List[Any], | |
| y_values: List[float], | |
| title: str = "Line Chart", | |
| x_label: str = "", | |
| y_label: str = "", | |
| filename: Optional[str] = None | |
| ) -> str: | |
| """ | |
| Create a line chart image (PNG). | |
| Args: | |
| x_values : X axis values (dates, labels, numbers) | |
| y_values : Y axis numeric values | |
| title : Chart title | |
| x_label : X axis label | |
| y_label : Y axis label | |
| filename : Optional output filename | |
| Returns: | |
| str: Download URL | |
| """ | |
| try: | |
| import matplotlib | |
| matplotlib.use("Agg") | |
| import matplotlib.pyplot as plt | |
| except ImportError: | |
| _install("matplotlib") | |
| import matplotlib | |
| matplotlib.use("Agg") | |
| import matplotlib.pyplot as plt | |
| try: | |
| fname = filename or f"linechart_{uuid.uuid4().hex[:8]}.png" | |
| if not fname.endswith(".png"): | |
| fname += ".png" | |
| out_path = OUTPUT_DIR / fname | |
| fig, ax = plt.subplots(figsize=(10, 6)) | |
| ax.plot(x_values, y_values, color="black", linewidth=2, marker="o", markersize=5) | |
| ax.fill_between(range(len(x_values)), y_values, alpha=0.1, color="black") | |
| ax.set_title(title, fontsize=16, fontweight="bold") | |
| ax.set_xlabel(x_label, fontsize=12) | |
| ax.set_ylabel(y_label, fontsize=12) | |
| ax.set_xticks(range(len(x_values))) | |
| ax.set_xticklabels([str(x) for x in x_values], rotation=45, ha="right") | |
| ax.spines["top"].set_visible(False) | |
| ax.spines["right"].set_visible(False) | |
| plt.tight_layout() | |
| plt.savefig(str(out_path), dpi=150, bbox_inches="tight") | |
| plt.close() | |
| return f"β Line chart created!\nπ₯ Download: {_url(fname)}" | |
| except Exception as e: | |
| return f"Line chart error: {str(e)}" | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # PIE CHART | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def create_pie_chart( | |
| labels: List[str], | |
| values: List[float], | |
| title: str = "Pie Chart", | |
| filename: Optional[str] = None | |
| ) -> str: | |
| """ | |
| Create a pie chart image (PNG). | |
| Args: | |
| labels : Slice labels | |
| values : Slice values | |
| title : Chart title | |
| filename : Optional output filename | |
| Returns: | |
| str: Download URL | |
| """ | |
| try: | |
| import matplotlib | |
| matplotlib.use("Agg") | |
| import matplotlib.pyplot as plt | |
| except ImportError: | |
| _install("matplotlib") | |
| import matplotlib | |
| matplotlib.use("Agg") | |
| import matplotlib.pyplot as plt | |
| try: | |
| fname = filename or f"piechart_{uuid.uuid4().hex[:8]}.png" | |
| if not fname.endswith(".png"): | |
| fname += ".png" | |
| out_path = OUTPUT_DIR / fname | |
| greys = [str(round(i / len(labels), 2)) for i in range(len(labels))] | |
| fig, ax = plt.subplots(figsize=(8, 8)) | |
| wedges, texts, autotexts = ax.pie( | |
| values, labels=labels, autopct="%1.1f%%", | |
| colors=greys, startangle=90, | |
| wedgeprops={"edgecolor": "white", "linewidth": 2} | |
| ) | |
| ax.set_title(title, fontsize=16, fontweight="bold") | |
| plt.tight_layout() | |
| plt.savefig(str(out_path), dpi=150, bbox_inches="tight") | |
| plt.close() | |
| return f"β Pie chart created!\nπ₯ Download: {_url(fname)}" | |
| except Exception as e: | |
| return f"Pie chart error: {str(e)}" | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # QR CODE | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def create_qr_code( | |
| data: str, | |
| filename: Optional[str] = None | |
| ) -> str: | |
| """ | |
| Generate a QR code image (PNG). | |
| Args: | |
| data : Text or URL to encode in the QR code | |
| filename : Optional output filename | |
| Returns: | |
| str: Download URL for the QR code image | |
| """ | |
| try: | |
| import qrcode | |
| except ImportError: | |
| _install("qrcode[pil]") | |
| import qrcode | |
| try: | |
| fname = filename or f"qrcode_{uuid.uuid4().hex[:8]}.png" | |
| if not fname.endswith(".png"): | |
| fname += ".png" | |
| out_path = OUTPUT_DIR / fname | |
| qr = qrcode.QRCode( | |
| version=1, | |
| error_correction=qrcode.constants.ERROR_CORRECT_H, | |
| box_size=10, | |
| border=4, | |
| ) | |
| qr.add_data(data) | |
| qr.make(fit=True) | |
| img = qr.make_image(fill_color="black", back_color="white") | |
| img.save(str(out_path)) | |
| return f"β QR code created for: {data[:50]}\nπ₯ Download: {_url(fname)}" | |
| except Exception as e: | |
| return f"QR code error: {str(e)}" | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # IMAGE RESIZE / CONVERT | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def resize_image( | |
| image_b64: str, | |
| width: int, | |
| height: int, | |
| filename: Optional[str] = None | |
| ) -> str: | |
| """ | |
| Resize an image from base64 input. | |
| Args: | |
| image_b64 : Base64 encoded image | |
| width : Target width in pixels | |
| height : Target height in pixels | |
| filename : Optional output filename | |
| Returns: | |
| str: Download URL for the resized image | |
| """ | |
| try: | |
| from PIL import Image | |
| import io, base64 | |
| except ImportError: | |
| _install("Pillow") | |
| from PIL import Image | |
| import io, base64 | |
| try: | |
| fname = filename or f"resized_{uuid.uuid4().hex[:8]}.png" | |
| if not fname.endswith(".png"): | |
| fname += ".png" | |
| out_path = OUTPUT_DIR / fname | |
| img_bytes = base64.b64decode(image_b64) | |
| img = Image.open(io.BytesIO(img_bytes)) | |
| img = img.resize((width, height), Image.LANCZOS) | |
| img.save(str(out_path)) | |
| return f"β Image resized to {width}x{height}\nπ₯ Download: {_url(fname)}" | |
| except Exception as e: | |
| return f"Image resize error: {str(e)}" | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # ZIP CREATOR | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def create_zip( | |
| file_paths: List[str], | |
| zip_filename: Optional[str] = None | |
| ) -> str: | |
| """ | |
| Create a ZIP archive from a list of files in the output folder. | |
| Args: | |
| file_paths : List of filenames in the agent_outputs folder to zip | |
| zip_filename : Optional output zip filename | |
| Returns: | |
| str: Download URL for the ZIP file | |
| """ | |
| import zipfile | |
| try: | |
| fname = zip_filename or f"archive_{uuid.uuid4().hex[:8]}.zip" | |
| if not fname.endswith(".zip"): | |
| fname += ".zip" | |
| out_path = OUTPUT_DIR / fname | |
| with zipfile.ZipFile(str(out_path), "w", zipfile.ZIP_DEFLATED) as zf: | |
| for fp in file_paths: | |
| full = OUTPUT_DIR / fp | |
| if full.exists(): | |
| zf.write(str(full), fp) | |
| else: | |
| log.warning(f"File not found for zip: {fp}") | |
| return f"β ZIP archive created with {len(file_paths)} files\nπ₯ Download: {_url(fname)}" | |
| except Exception as e: | |
| return f"ZIP creation error: {str(e)}" | |