0Learn commited on
Commit
61a8d78
·
verified ·
1 Parent(s): a01a1ba

Create backend.py

Browse files
Files changed (1) hide show
  1. backend.py +64 -0
backend.py ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, HTTPException
2
+ from pydantic import BaseModel, field_validator
3
+ import math
4
+ import re
5
+
6
+ app = FastAPI()
7
+
8
+ ALLOWED_FUNCTIONS = {'sin', 'cos', 'tan', 'log', 'ln', 'sqrt', 'abs', 'pow'}
9
+ ALLOWED_CONSTANTS = {'pi', 'e'}
10
+
11
+ class Expression(BaseModel):
12
+ expr: str
13
+
14
+ @field_validator('expr')
15
+ @classmethod
16
+ def validate_expression(cls, v: str) -> str:
17
+ if not v:
18
+ raise ValueError("Expression cannot be empty")
19
+
20
+ # Check for invalid characters
21
+ valid_chars = set('0123456789.+-*/()^ \t\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
22
+ invalid_chars = set(v) - valid_chars
23
+ if invalid_chars:
24
+ raise ValueError(f"Invalid characters found: {', '.join(invalid_chars)}")
25
+
26
+ # Check for invalid function names or constants
27
+ tokens = re.findall(r'\b[a-zA-Z_]\w*\b', v)
28
+ invalid_tokens = [token for token in tokens if token not in ALLOWED_FUNCTIONS and token not in ALLOWED_CONSTANTS]
29
+ if invalid_tokens:
30
+ raise ValueError(f"Invalid function or constant names: {', '.join(invalid_tokens)}")
31
+
32
+ return v
33
+
34
+ @app.post("/calculate")
35
+ async def calculate_api(expression: Expression):
36
+ try:
37
+ result = evaluate_expression(expression.expr)
38
+ return {"result": result}
39
+ except ValueError as e:
40
+ raise HTTPException(status_code=400, detail=str(e))
41
+ except Exception as e:
42
+ raise HTTPException(status_code=500, detail=f"An unexpected error occurred: {str(e)}")
43
+
44
+ def evaluate_expression(expr: str) -> float:
45
+ safe_dict = {
46
+ 'sin': math.sin, 'cos': math.cos, 'tan': math.tan,
47
+ 'log': math.log10, 'ln': math.log, 'sqrt': math.sqrt,
48
+ 'pi': math.pi, 'e': math.e,
49
+ 'abs': abs, 'pow': pow
50
+ }
51
+ try:
52
+ # Replace '^' with '**' for exponentiation
53
+ expr = expr.replace('^', '**')
54
+ return eval(expr, {"__builtins__": None}, safe_dict)
55
+ except ZeroDivisionError:
56
+ raise ValueError("Division by zero is not allowed")
57
+ except ValueError as e:
58
+ raise ValueError(f"Math domain error: {str(e)}")
59
+ except Exception as e:
60
+ raise ValueError(f"Invalid expression: {str(e)}")
61
+
62
+ if __name__ == "__main__":
63
+ import uvicorn
64
+ uvicorn.run(app, host="0.0.0.0", port=8000)