eihab2342/code-efficiency
0
1# src/api/main.py2"""3FastAPI — entry point للـ API4 5تشغيل:6 uvicorn src.api.main:app --reload --port 80007 8Swagger UI:9 http://localhost:8000/docs10"""11from fastapi import FastAPI, HTTPException12from pydantic import BaseModel13from contextlib import asynccontextmanager14 15from src.model.predictor import Predictor, PredictResult16from src.utils.logger import get_logger17 18log = get_logger("api")19 20# ── Startup: يحمّل الموديل مرة واحدة ──────────────────21predictor: Predictor | None = None22 23@asynccontextmanager24async def lifespan(app: FastAPI):25 global predictor26 log.info("تحميل الموديل...")27 predictor = Predictor()28 log.info("API جاهز ✓")29 yield30 31app = FastAPI(32 title="Code Efficiency Optimizer",33 description="يستقبل كود Python ويرجعه محسَّناً باستخدام seq2seq model مدرّب على PIE4Perf.",34 version="1.0.0",35 lifespan=lifespan,36)37 38 39# ── Schemas ────────────────────────────────────────────40 41class OptimizeRequest(BaseModel):42 code: str43 44 model_config = {45 "json_schema_extra": {46 "example": {47 "code": "result = []\nfor x in items:\n result.append(x * 2)"48 }49 }50 }51 52class OptimizeResponse(BaseModel):53 original_code: str54 optimized_code: str55 changes: list[str]56 estimated_speedup: float57 58 59# ── Endpoints ──────────────────────────────────────────60 61@app.get("/health", tags=["System"])62def health():63 """فحص حالة الـ server والموديل"""64 return {65 "status": "ok",66 "model_loaded": predictor is not None,67 }68 69 70@app.post("/optimize", response_model=OptimizeResponse, tags=["Optimizer"])71def optimize(req: OptimizeRequest):72 """73 يستقبل كود Python ويرجع النسخة المحسَّنة.74 75 - **code**: الكود المراد تحسينه76 """77 if not req.code.strip():78 raise HTTPException(status_code=400, detail="الكود فاضي")79 80 result: PredictResult = predictor.predict(req.code)81 82 return OptimizeResponse(83 original_code=result.original_code,84 optimized_code=result.optimized_code,85 changes=result.changes,86 estimated_speedup=result.estimated_speedup,87 )88 89 90@app.post("/analyze", tags=["Optimizer"])91def analyze(req: OptimizeRequest):92 """93 يحلل الكود بدون تعديل — يكشف المشاكل والـ complexity.94 """95 import ast as _ast96 97 if not req.code.strip():98 raise HTTPException(status_code=400, detail="الكود فاضي")99 100 try:101 tree = _ast.parse(req.code)102 valid = True103 syntax_error = None104 except SyntaxError as e:105 return {"valid": False, "syntax_error": str(e)}106 107 # حساب cyclomatic complexity بسيط108 complexity = 1109 loops = 0110 for node in _ast.walk(tree):111 if isinstance(node, (_ast.If, _ast.For, _ast.While,112 _ast.ExceptHandler, _ast.With)):113 complexity += 1114 if isinstance(node, (_ast.For, _ast.While)):115 loops += 1116 117 return {118 "valid": True,119 "lines": len([l for l in req.code.splitlines() if l.strip()]),120 "cyclomatic_complexity": complexity,121 "loops": loops,122 }123 