Spaces:
Build error
Build error
File size: 7,390 Bytes
b26fccc 82904d0 b3fb970 edb1c5f b26fccc b6522d9 b3fb970 edb1c5f 82904d0 edb1c5f 82904d0 b6522d9 82904d0 576154a 82904d0 edb1c5f b26fccc b6522d9 b26fccc b6522d9 b26fccc edb1c5f b6522d9 b26fccc edb1c5f b26fccc edb1c5f b26fccc edb1c5f b26fccc edb1c5f b26fccc edb1c5f b26fccc b3fb970 edb1c5f 82904d0 edb1c5f 82904d0 edb1c5f 82904d0 edb1c5f 82904d0 edb1c5f 82904d0 b26fccc b6522d9 b26fccc 82904d0 b3fb970 edb1c5f b3fb970 82904d0 b26fccc edb1c5f b26fccc b3fb970 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
import autopep8
import subprocess
import time
import re
import os
from pathlib import Path
from fastapi.middleware.cors import CORSMiddleware
import tempfile
app = FastAPI(title="Code Evaluation & Optimization API")
# CORS Configuration
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Environment Setup - Modified for Hugging Face Spaces
CACHE_DIR = Path(os.getenv("HF_HOME", "/tmp/huggingface"))
CACHE_DIR.mkdir(parents=True, exist_ok=True)
os.environ["TRANSFORMERS_CACHE"] = str(CACHE_DIR)
os.environ["HF_HOME"] = str(CACHE_DIR)
# Load AI Model - Using smaller model for Spaces compatibility
MODEL_NAME = "codellama/CodeLlama-7b-instruct-hf" # More suitable for API use
try:
tokenizer = AutoTokenizer.from_pretrained(
MODEL_NAME,
cache_dir=str(CACHE_DIR))
model = AutoModelForCausalLM.from_pretrained(
MODEL_NAME,
device_map="auto",
torch_dtype=torch.float16,
cache_dir=str(CACHE_DIR))
except Exception as e:
print(f"Model loading warning: {str(e)}")
model = None
tokenizer = None
# Request Model
class CodeRequest(BaseModel):
code: str
language: str = "python"
def create_temp_file(code: str, extension: str) -> str:
"""Create temporary file in writable directory with proper permissions"""
temp_dir = "/tmp/code_files"
os.makedirs(temp_dir, exist_ok=True)
fd, path = tempfile.mkstemp(suffix=f".{extension}", dir=temp_dir)
with os.fdopen(fd, 'w') as tmp:
tmp.write(code)
os.chmod(path, 0o777) # Ensure executable permissions
return path
def cleanup_temp_files():
"""Clean up temporary files"""
temp_dir = "/tmp/code_files"
if os.path.exists(temp_dir):
for filename in os.listdir(temp_dir):
file_path = os.path.join(temp_dir, filename)
try:
if os.path.isfile(file_path):
os.unlink(file_path)
except Exception as e:
print(f"Error deleting {file_path}: {e}")
# Helper Functions
def evaluate_code(user_code: str, lang: str) -> dict:
"""Evaluate code for correctness, performance, and security"""
start_time = time.time()
file_ext = {"python": "py", "java": "java", "cpp": "cpp", "javascript": "js"}.get(lang, "txt")
try:
filename = create_temp_file(user_code, file_ext)
commands = {
"python": ["python3", filename],
"java": ["javac", filename, "&&", "java", filename.replace(".java", "")],
"cpp": ["g++", filename, "-o", f"{filename}.out", "&&", f"./{filename}.out"],
"javascript": ["node", filename]
}
if lang not in commands:
return {"status": "error", "message": "Unsupported language", "score": 0}
result = subprocess.run(
" ".join(commands[lang]),
capture_output=True,
text=True,
timeout=5,
shell=True
)
exec_time = time.time() - start_time
correctness = 1 if result.returncode == 0 else 0
error_message = None if correctness else result.stderr.strip()
# Scoring logic
readability_score = 20 if len(user_code) < 200 else 10
efficiency_score = 30 if exec_time < 1 else 10
security_score = 20 if "eval(" not in user_code and "exec(" not in user_code else 0
total_score = (correctness * 50) + readability_score + efficiency_score + security_score
feedback = []
if correctness == 0:
feedback.append("β Error in Code Execution! Check syntax or logic errors.")
feedback.append(f"π Error Details: {error_message}")
else:
feedback.append("β
Code executed successfully!")
if efficiency_score < 30:
feedback.append("β‘ Performance Issue: Code took longer to execute. Optimize loops or calculations.")
if readability_score < 20:
feedback.append("π Readability Issue: Code is lengthy. Break into smaller functions.")
if security_score == 0:
feedback.append("π Security Risk: Avoid using eval() or exec().")
return {
"status": "success" if correctness else "error",
"execution_time": round(exec_time, 3) if correctness else None,
"score": max(0, min(100, total_score)),
"feedback": "\n".join(feedback),
"error_details": error_message if not correctness else None
}
except subprocess.TimeoutExpired:
return {"status": "error", "message": "Execution timed out", "score": 0}
except Exception as e:
return {"status": "error", "message": str(e), "score": 0}
finally:
cleanup_temp_files()
def optimize_code_ai(user_code: str, lang: str) -> str:
"""Generate optimized code using AI"""
if model is None or tokenizer is None:
raise HTTPException(status_code=503, detail="AI service temporarily unavailable")
try:
if lang == "python":
user_code = autopep8.fix_code(user_code)
user_code = re.sub(r"eval\((.*)\)", r"int(\1) # Removed eval for security", user_code)
user_code = re.sub(r"/ 0", "/ 1 # Fixed division by zero", user_code)
prompt = f"""Optimize this {lang} code for better performance and readability:
```{lang}
{user_code}
"""
inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
with torch.no_grad():
outputs = model.generate(**inputs, max_length=1024, temperature=0.7)
optimized_code = tokenizer.decode(outputs[0], skip_special_tokens=True)
# Extract code between the last code block markers
code_blocks = re.findall(r'```(?:python)?\n(.*?)\n```', optimized_code, re.DOTALL)
if code_blocks:
optimized_code = code_blocks[-1] # Get the last code block
return optimized_code.strip() if optimized_code else user_code
except Exception as e:
raise HTTPException(status_code=500, detail=f"AI optimization failed: {str(e)}")
# API Endpoints
@app.post("/evaluate")
async def evaluate_endpoint(request: CodeRequest):
try:
result = evaluate_code(request.code, request.language)
return {"status": "success", "result": result}
except Exception as e:
raise HTTPException(status_code=400, detail=str(e))
@app.post("/optimize")
async def optimize_endpoint(request: CodeRequest):
try:
optimized = optimize_code_ai(request.code, request.language)
return {"status": "success", "optimized_code": optimized}
except Exception as e:
raise HTTPException(status_code=400, detail=str(e))
@app.get("/")
def health_check():
return {
"status": "API is running",
"model": MODEL_NAME if model else "Not loaded",
"endpoints": {
"evaluate": "POST /evaluate",
"optimize": "POST /optimize"
}
}
@app.on_event("shutdown")
def shutdown_event():
cleanup_temp_files()
if __name__ == "__main__":
import uvicorn
uvicorn.run("main:app", host="0.0.0.0", port=7860) |