Soly663/Genetic_Algorithm-choosingFeature
0
1from fastapi import FastAPI, Request
2from fastapi.responses import JSONResponse
3from pydantic import BaseModel, Field
4import warnings
5
6# Import GA logic
7from main_ga import run_genetic_algorithm
8
9warnings.filterwarnings("ignore")
10
11# --- FastAPI App Setup ---
12app = FastAPI(
13 title="Genetic Algorithm Feature Selection API",
14 version="1.0",
15 description="Backend for running Genetic Algorithm on feature selection (BIA601 Project)"
16)
17
18# --- Request Model with defaults ---
19class GAParams(BaseModel):
20 population_size: int = Field(50, ge=1, description="Size of GA population")
21 generations: int = Field(100, ge=1, description="Number of generations")
22 mutation_rate: float = Field(0.05, ge=0.0, le=1.0, description="Mutation rate (0-1)")
23
24# --- Exception Handlers ---
25@app.exception_handler(Exception)
26async def global_exception_handler(request: Request, exc: Exception):
27 return JSONResponse(
28 status_code=500,
29 content={"status": "error", "message": str(exc)}
30 )
31
32@app.exception_handler(422)
33async def validation_exception_handler(request: Request, exc):
34 return JSONResponse(
35 status_code=422,
36 content={
37 "status": "error",
38 "message": "Validation Error: check request body or types",
39 "details": exc.errors()
40 }
41 )
42
43# --- Routes ---
44@app.get("/")
45def home():
46 return {
47 "message": "๐ Genetic Algorithm API is running!",
48 "usage": "Send POST request to /run_ga with population_size, generations, mutation_rate"
49 }
50
51@app.post("/run_ga")
52async def run_ga(request: Request):
53 """
54 Run the GA using main-ga.py.
55 Accepts JSON input; uses default values if keys are missing.
56 """
57 try:
58 # Read JSON safely
59 json_data = await request.json()
60 except Exception:
61 json_data = {}
62
63 # Extract parameters with defaults if missing
64 population_size = json_data.get("population_size", 50)
65 generations = json_data.get("generations", 100)
66 mutation_rate = json_data.get("mutation_rate", 0.05)
67
68 # Optionally, validate types manually
69 if not isinstance(population_size, int) or population_size < 1:
70 return {"status": "error", "message": "population_size must be a positive integer"}
71 if not isinstance(generations, int) or generations < 1:
72 return {"status": "error", "message": "generations must be a positive integer"}
73 if not isinstance(mutation_rate, (float, int)) or not (0 <= mutation_rate <= 1):
74 return {"status": "error", "message": "mutation_rate must be between 0 and 1"}
75
76 # Run the GA (main-ga.py uses defaults internally; no need to pass params)
77 try:
78 result = run_genetic_algorithm()
79 if not isinstance(result, list):
80 return {"status": "error", "message": "GA did not return a valid chromosome list"}
81
82 return {
83 "status": "success",
84 "parameters": {
85 "population_size": population_size,
86 "generations": generations,
87 "mutation_rate": mutation_rate
88 },
89 "result": {
90 "selected_features": sum(result),
91 "chromosome": result
92 }
93 }
94
95 except Exception as e:
96 return {"status": "error", "message": str(e)}
97 