sudoku-solver / main.py
sumangouda's picture
Initial commit - dockerized sudoku solver
63343b8
Raw
History Blame Contribute Delete
2.1 kB
import io
import uvicorn
from fastapi import FastAPI, UploadFile, File, HTTPException
from fastapi.responses import JSONResponse
from fastapi.staticfiles import StaticFiles
from tensorflow.keras.models import load_model
from PIL import Image
from services.image_ops import process_image
from services.digit_utils import extract_and_clean_cells
from models.predict import predict_sudoku_grid
from services.sudoku_solver import SudokuSolver
app = FastAPI()
MODEL = load_model("models/emnist_digit_cnn.keras")
@app.post("/predict")
async def run_sudoku_pipeline(file: UploadFile = File(...)):
"""
Processes image -> Predicts digits -> Solves the grid -> Returns result.
"""
try:
try:
contents = await file.read()
img = Image.open(io.BytesIO(contents))
except Exception:
raise HTTPException(status_code=400, detail="Could not decode image.")
p_img = process_image(img)
cleaned_cells = extract_and_clean_cells(p_img)
sudoku_predictions = predict_sudoku_grid(cleaned_cells, MODEL)
grid_9x9 = []
for i in range(9):
row = []
for j in range(9):
val = sudoku_predictions[i*9 + j]
row.append(int(val) if isinstance(val, (int, str)) and str(val).isdigit() else 0)
grid_9x9.append(row)
print(grid_9x9)
solver = SudokuSolver(grid_9x9)
if solver.solve():
flat_solved = [int(item) for row in solver.board for item in row]
return JSONResponse(content={"solved_grid": flat_solved})
else:
return JSONResponse(
content={"error": "The puzzle is unsolvable. Check for digit recognition errors."},
status_code=400
)
except HTTPException as he:
raise he
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
app.mount("/", StaticFiles(directory="static", html=True), name="static")
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)