Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| from fastapi import FastAPI, HTTPException | |
| from pydantic import BaseModel, field_validator | |
| from frontend import create_interface | |
| import math | |
| import re | |
| import os | |
| app = FastAPI() | |
| ALLOWED_FUNCTIONS = {'sin', 'cos', 'tan', 'log', 'ln', 'sqrt', 'abs', 'pow'} | |
| ALLOWED_CONSTANTS = {'pi', 'e'} | |
| class Expression(BaseModel): | |
| expr: str | |
| def validate_expression(cls, v: str) -> str: | |
| if not v: | |
| raise ValueError("Expression cannot be empty") | |
| # Check for invalid characters | |
| valid_chars = set('0123456789.+-*/()^ \t\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') | |
| invalid_chars = set(v) - valid_chars | |
| if invalid_chars: | |
| raise ValueError(f"Invalid characters found: {', '.join(invalid_chars)}") | |
| # Check for invalid function names or constants | |
| tokens = re.findall(r'\b[a-zA-Z_]\w*\b', v) | |
| invalid_tokens = [token for token in tokens if token not in ALLOWED_FUNCTIONS and token not in ALLOWED_CONSTANTS] | |
| if invalid_tokens: | |
| raise ValueError(f"Invalid function or constant names: {', '.join(invalid_tokens)}") | |
| return v | |
| async def calculate_api(expression: Expression): | |
| try: | |
| result = evaluate_expression(expression.expr) | |
| return {"result": result} | |
| except ValueError as e: | |
| raise HTTPException(status_code=400, detail=str(e)) | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=f"An unexpected error occurred: {str(e)}") | |
| def evaluate_expression(expr: str) -> float: | |
| safe_dict = { | |
| 'sin': math.sin, 'cos': math.cos, 'tan': math.tan, | |
| 'log': math.log10, 'ln': math.log, 'sqrt': math.sqrt, | |
| 'pi': math.pi, 'e': math.e, | |
| 'abs': abs, 'pow': pow | |
| } | |
| try: | |
| # Replace '^' with '**' for exponentiation | |
| expr = expr.replace('^', '**') | |
| return eval(expr, {"__builtins__": None}, safe_dict) | |
| except ZeroDivisionError: | |
| raise ValueError("Division by zero is not allowed") | |
| except ValueError as e: | |
| raise ValueError(f"Math domain error: {str(e)}") | |
| except Exception as e: | |
| raise ValueError(f"Invalid expression: {str(e)}") | |
| # Create the Gradio interface | |
| iface = create_interface() | |
| # Mount the Gradio app | |
| app = gr.mount_gradio_app(app, iface, path="/") | |
| if __name__ == "__main__": | |
| import uvicorn | |
| port = int(os.environ.get("PORT", 7860)) | |
| uvicorn.run(app, host="0.0.0.0", port=port) |