Spaces:
Runtime error
Runtime error
| import os, sys | |
| from dotenv import load_dotenv | |
| load_dotenv() | |
| sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) | |
| from download_assets import download_assets | |
| download_assets() | |
| import gradio as gr | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from fastapi import File, UploadFile, HTTPException | |
| from fastapi.responses import JSONResponse | |
| from pydantic import BaseModel | |
| from typing import Optional | |
| from PIL import Image | |
| import io, base64, json | |
| from src.predict import predict_from_bytes | |
| from src.explain import explain_from_bytes | |
| from src.llm_explain import explain_prediction, answer_question | |
| from config import CLASS_LABELS | |
| def run_predict(image_bytes, do_explain, do_llm): | |
| result = predict_from_bytes(image_bytes) | |
| heatmap_b64 = None | |
| if do_explain: | |
| try: | |
| pred_idx = CLASS_LABELS[result["predicted_class"]] | |
| heatmap_b64 = explain_from_bytes(image_bytes, pred_idx) | |
| except: pass | |
| explanation = None | |
| if do_llm: | |
| try: | |
| explanation = explain_prediction( | |
| predicted_class=result["predicted_class"], | |
| confidence=result["confidence"], | |
| probabilities=result["probabilities"], | |
| ) | |
| except Exception as e: | |
| explanation = str(e) | |
| return result, heatmap_b64, explanation | |
| def gradio_predict(image: Image.Image): | |
| buf = io.BytesIO() | |
| image.save(buf, format="JPEG") | |
| result, heatmap_b64, explanation = run_predict(buf.getvalue(), True, True) | |
| heatmap_img = Image.open(io.BytesIO(base64.b64decode(heatmap_b64))) if heatmap_b64 else None | |
| return heatmap_img, {result["predicted_class"]: result["confidence"]}, explanation or "" | |
| with gr.Blocks(title="DermAI") as demo: | |
| gr.Markdown("# DermAI — Skin Lesion Classifier\nFrontend: [GitHub Pages](https://ranjithtkm445-blip.github.io/skin-lesion-ai)") | |
| with gr.Row(): | |
| inp = gr.Image(type="pil", label="Upload Image") | |
| with gr.Column(): | |
| heatmap = gr.Image(label="Grad-CAM") | |
| label_out = gr.Label(label="Prediction") | |
| explanation_out = gr.Textbox(label="Clinical Explanation", lines=6) | |
| btn = gr.Button("Analyze", variant="primary") | |
| btn.click(gradio_predict, inputs=inp, outputs=[heatmap, label_out, explanation_out]) | |
| # Mount custom API routes on Gradio internal FastAPI app | |
| app = demo.app | |
| app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"]) | |
| def health(): | |
| return {"status": "ok"} | |
| async def predict(file: UploadFile = File(...), explain: bool = True, llm_explain: bool = True): | |
| if not file.content_type.startswith("image/"): | |
| raise HTTPException(status_code=400, detail="File must be an image.") | |
| image_bytes = await file.read() | |
| result, heatmap_b64, explanation = run_predict(image_bytes, explain, llm_explain) | |
| return { | |
| "predicted_class": result["predicted_class"], | |
| "class_name": result["class_name"], | |
| "confidence": result["confidence"], | |
| "probabilities": result["probabilities"], | |
| "heatmap_base64": heatmap_b64, | |
| "explanation": explanation, | |
| } | |
| async def ask(question: str, predicted_class: Optional[str] = None): | |
| try: | |
| answer = answer_question(question, predicted_class) | |
| return {"answer": answer} | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=str(e)) | |
| if __name__ == "__main__": | |
| demo.launch(server_name="0.0.0.0", server_port=7860) |