Spaces:
Running
Running
| from fastapi import FastAPI, HTTPException | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from pydantic import BaseModel | |
| from typing import List, Dict, Any | |
| import numpy as np | |
| # Import your solver logic | |
| from gss_solver import golden_section_search | |
| app = FastAPI( | |
| title="Golden Section Search API", | |
| description="An API to find function minima using the Golden Section Search algorithm.", | |
| version="1.0.0", | |
| ) | |
| # --- CORS Configuration --------------------------------------------------- | |
| # This allows your frontend (running on a different port) to talk to this backend. | |
| origins = [ | |
| "*" # Allow all origins for development | |
| ] | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=origins, | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| # --- In-Memory Storage ---------------------------------------------------- | |
| # A simple list to store the history of calculations for the current session. | |
| session_history: List[Dict[str, Any]] = [] | |
| # --- Pydantic Models ------------------------------------------------------ | |
| # These models define the expected structure of the request and response data. | |
| class SolverInput(BaseModel): | |
| func_str: str | |
| a: float | |
| b: float | |
| tol: float = 1e-4 | |
| mode: str = 'minimize' | |
| class SolverResult(BaseModel): | |
| x_min: float | |
| f_min: float | |
| iterations: list | |
| num_iterations: int | |
| plot_data: dict | None | |
| # --- API Endpoints -------------------------------------------------------- | |
| def read_root(): | |
| return {"message": "Welcome to the GSS Solver API. Visit /docs for details."} | |
| def solve_function(data: SolverInput): | |
| """ | |
| Receives function details, performs the Golden Section Search, | |
| and returns the result including a plot. | |
| """ | |
| try: | |
| # If maximizing, we minimize the negative of the function | |
| func_to_solve = f"-({data.func_str})" if data.mode == 'maximize' else data.func_str | |
| # Perform the calculation using your existing solver function | |
| result = golden_section_search( | |
| func_str=func_to_solve, | |
| a=data.a, | |
| b=data.b, | |
| tol=data.tol | |
| ) | |
| # Adjust f_min back if we were maximizing | |
| if data.mode == 'maximize': | |
| result['f_min'] = -result['f_min'] | |
| for it in result['iterations']: | |
| it['f_x1'] = -it['f_x1'] | |
| it['f_x2'] = -it['f_x2'] | |
| # Generate plot data as x/y arrays for Plotly on the frontend | |
| from sympy import symbols, sympify, lambdify | |
| x_sym = symbols('x') | |
| expr = sympify(data.func_str) | |
| func = lambdify(x_sym, expr, modules=['numpy']) | |
| # Create x values with some padding around the bounds | |
| padding = (data.b - data.a) * 0.1 | |
| x_vals = np.linspace(data.a - padding, data.b + padding, 500) | |
| y_vals = func(x_vals) | |
| plot_data = { | |
| "x": x_vals.tolist(), | |
| "y": y_vals.tolist() | |
| } | |
| # Prepare the response | |
| response_data = { | |
| "x_min": result['x_min'], | |
| "f_min": result['f_min'], | |
| "iterations": result['iterations'], | |
| "num_iterations": result['num_iterations'], | |
| "plot_data": plot_data | |
| } | |
| if 'warning' in result: | |
| response_data['warning'] = result['warning'] | |
| # Add to session history | |
| history_entry = {**response_data, "function": data.func_str, "bounds": {"a": data.a, "b": data.b}, "mode": data.mode, "tolerance": data.tol} | |
| session_history.insert(0, history_entry) | |
| return response_data | |
| except ValueError as e: | |
| raise HTTPException(status_code=400, detail=str(e)) | |
| except Exception as e: | |
| # Catch any other unexpected errors during computation | |
| raise HTTPException(status_code=500, detail=f"An unexpected error occurred: {str(e)}") | |
| def get_history(): | |
| """ | |
| Returns the list of all calculations performed in the current session. | |
| """ | |
| return session_history | |
| def clear_history(): | |
| """ | |
| Clears the session history. | |
| """ | |
| session_history.clear() | |
| return {"message": "History cleared successfully."} | |
| if __name__ == "__main__": | |
| import uvicorn | |
| print("Starting FastAPI server...") | |
| print("Run with: uvicorn main:app --reload") | |
| print("Access the API docs at http://localhost:8000/docs") | |
| uvicorn.run("main:app", host="127.0.0.1", port=8000, reload=True) | |