| import os |
| import ast |
| import io |
| import sys |
| import numpy as np |
| import pandas as pd |
| import scipy |
| from groq import Groq |
|
|
| from pathlib import Path |
| import pandas as pd |
| import mimetypes |
| import base64 |
|
|
| ALLOWED_MODULES = {"numpy", "pandas", "scipy"} |
|
|
| def interpret_python_math_code(python_code: str) -> str: |
| """ |
| Interprets a string of Python code to perform math calculations. |
| |
| Security Note: This function uses exec(). While it attempts to restrict |
| imports to numpy, pandas, and scipy, and runs with a restricted |
| global scope, executing arbitrary code always carries risks. Ensure |
| that input code is from a trusted source or properly sanitized. |
| |
| The code must only import modules from the allowed list: numpy, pandas, scipy. |
| Submodules of these (e.g., numpy.linalg, scipy.stats) are permitted. |
| For example: |
| 'import numpy as np' is allowed. |
| 'from scipy.stats import norm' is allowed. |
| 'import os' is NOT allowed. |
| |
| To return a result, the code should either: |
| 1. End with an expression (e.g., '1 + 1' or 'np.array([1,2,3]).sum()'). |
| 2. Assign the result to a variable named '_result' (e.g., '_result = my_calculation'). |
| |
| Print statements will also be captured and returned along with the result. |
| """ |
| |
| try: |
| tree = ast.parse(python_code) |
| for node in tree.body: |
| if isinstance(node, ast.Import): |
| for alias in node.names: |
| root_module = alias.name.split('.')[0] |
| if root_module not in ALLOWED_MODULES: |
| return (f"Error: Import of '{alias.name}' is not allowed. " |
| f"Only modules from {list(ALLOWED_MODULES)} are permitted.") |
| elif isinstance(node, ast.ImportFrom): |
| if node.module: |
| root_module = node.module.split('.')[0] |
| if root_module not in ALLOWED_MODULES: |
| return (f"Error: Import from '{node.module}' is not allowed. " |
| f"Only modules from {list(ALLOWED_MODULES)} are permitted.") |
| except SyntaxError as e: |
| return f"Syntax Error in input code: {e}" |
|
|
| |
| restricted_globals = { |
| "__builtins__": { |
| "print": print, |
| "abs": abs, "round": round, "min": min, "max": max, "sum": sum, "len": len, |
| "range": range, "zip": zip, "enumerate": enumerate, |
| "int": int, "float": float, "str": str, "list": list, "dict": dict, "tuple": tuple, "set": set, |
| "True": True, "False": False, "None": None, |
| "__import__": __import__, |
| } |
| |
| |
| |
| } |
| local_vars = {} |
|
|
| |
| old_stdout = sys.stdout |
| redirected_output = io.StringIO() |
| sys.stdout = redirected_output |
|
|
| |
| calculated_value = None |
| result_source = "" |
| output_str = "" |
|
|
| try: |
| compiled_code = compile(python_code, '<string>', 'exec') |
| exec(compiled_code, restricted_globals, local_vars) |
| |
| |
| if "_result" in local_vars: |
| calculated_value = local_vars["_result"] |
| result_source = "variable '_result'" |
| |
| elif tree.body and isinstance(tree.body[-1], ast.Expr): |
| |
| if isinstance(tree.body[-1].value, ast.AST): |
| last_expr_ast = ast.Expression(body=tree.body[-1].value) |
| |
| compiled_expr = compile(last_expr_ast, '<string>', 'eval') |
| |
| calculated_value = eval(compiled_expr, restricted_globals, local_vars) |
| result_source = "last expression" |
| |
| sys.stdout = old_stdout |
| output_str = redirected_output.getvalue() |
|
|
| if calculated_value is not None: |
| return f"Result (from {result_source}):\n{calculated_value}\n\nCaptured Output:\n{output_str}".strip() |
| else: |
| return f"Executed successfully.\n\nCaptured Output:\n{output_str}\n(No specific result value found via '_result' variable or last expression evaluation.)".strip() |
|
|
| except Exception as e: |
| if sys.stdout == redirected_output: |
| sys.stdout = old_stdout |
| output_str = redirected_output.getvalue() |
| return f"Execution Error: {type(e).__name__}: {e}\n\nCaptured Output:\n{output_str}".strip() |
| finally: |
| |
| if sys.stdout == redirected_output: |
| sys.stdout = old_stdout |
|
|
|
|
| |
| def convert_audio_to_text(path_to_audio: str) -> str: |
| """ |
| Converts speech from an audio file into text. |
| Args: |
| path_to_audio (str): The path to the audio file to be transcribed. |
| Returns: |
| str: The transcribed text content of the audio file. |
| """ |
| |
| |
| if not isinstance(path_to_audio, str): |
| raise TypeError( |
| "Parameter 'path_to_audio' must be a string containing the file path." |
| ) |
| path = Path(path_to_audio).expanduser().resolve() |
| if not path.is_file(): |
| raise FileNotFoundError(f"No such audio file: {path}") |
|
|
| |
| client = Groq() |
| |
| |
| with open(path_to_audio, "rb") as audio_file: |
| |
| transcription = client.audio.transcriptions.create( |
| file=audio_file, |
| model="whisper-large-v3-turbo", |
| response_format="text", |
| language="en", |
| temperature=0.1 |
| ) |
|
|
| return transcription |
|
|
| |
| def analyze_image(path_to_image: str, question: str) -> str: |
| """ |
| Analyzes an image and generates a response to a given question based on the image's content. |
| |
| Args: |
| path_to_image (str): The path to the image file to be analyzed. |
| question (str): The question to be answered, based on the contents of the image. |
| |
| Returns: |
| str: The response from a VLM, typically a textual analysis or description based on the image. |
| """ |
|
|
| def encode_image(image_path): |
| with open(image_path, "rb") as image_file: |
| return base64.b64encode(image_file.read()).decode('utf-8') |
| |
| |
| mime_type, _ = mimetypes.guess_type(path_to_image) |
| if mime_type is None: |
| raise ValueError("Unsupported file type. Please provide a valid image.") |
|
|
| base64_image = encode_image(path_to_image) |
|
|
| |
| client = GroqClient() |
| |
| chat_completion = client.chat.completions.create( |
| messages=[ |
| { |
| "role": "user", |
| "content": [ |
| {"type": "text", "text": question}, |
| { |
| "type": "image_url", |
| "image_url": { |
| "url": f"data:{mime_type};base64,{base64_image}", |
| }, |
| }, |
| ], |
| } |
| ], |
| model="meta-llama/llama-4-scout-17b-16e-instruct", |
| ) |
| |
| return chat_completion.choices[0].message.content |
|
|
| |
| def read_csv_file(path_to_csv: str) -> str: |
| """ |
| Reads a CSV file from the specified path and returns its content as plain text. |
| |
| Args: |
| path_to_csv (str): The file path to the CSV file. |
| |
| Returns: |
| str: Content of the CSV file as plain text. |
| """ |
| try: |
| |
| df = pd.read_csv(path_to_csv) |
| |
| |
| return df.to_string(index=False) |
| except Exception as e: |
| return f"Error reading the CSV file: {e}" |
|
|
| |
| def read_xlsx_file(path_to_xlsx: str) -> str: |
| """ |
| Reads a XLSX file from the specified path and returns its content as plain text. |
| |
| Args: |
| path_to_xlsx (str): The file path to the XLSX file. |
| |
| Returns: |
| str: Content of the XLSX file as plain text. |
| """ |
| try: |
| |
| df = pd.read_excel(path_to_xlsx) |
| |
| |
| return df.to_string(index=False) |
| except Exception as e: |
| return f"Error reading the XLSX file: {e}" |