Spaces:
Runtime error
Runtime error
File size: 4,629 Bytes
98fed04 |
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 |
from flask import Flask, request, jsonify, render_template, send_from_directory
from transformers import AutoModelForImageClassification, AutoImageProcessor
from huggingface_hub import InferenceClient
from PIL import Image
import torch
import os
app = Flask(__name__)
# =======================================
# π Hugging Face LLM Token + InferenceClient
# =======================================
HUGGINGFACE_TOKEN = os.environ.get("HUGGINGFACE_TOKEN")
client = InferenceClient(
model="mistralai/Mistral-7B-Instruct-v0.1",
token=HUGGINGFACE_TOKEN
)
# =======================================
# π§ Load Skin Disease Model
# =======================================
print("Loading skin condition classifier...")
model_name = "Jayanth2002/dinov2-base-finetuned-SkinDisease"
image_model = AutoModelForImageClassification.from_pretrained(model_name)
processor = AutoImageProcessor.from_pretrained(model_name)
# Class labels
class_names = [
'Basal Cell Carcinoma', 'Darier_s Disease', 'Epidermolysis Bullosa Pruriginosa',
'Hailey-Hailey Disease', 'Herpes Simplex', 'Impetigo', 'Larva Migrans',
'Leprosy Borderline', 'Leprosy Lepromatous', 'Leprosy Tuberculoid', 'Lichen Planus',
'Lupus Erythematosus Chronicus Discoides', 'Melanoma', 'Molluscum Contagiosum',
'Mycosis Fungoides', 'Neurofibromatosis', 'Papilomatosis Confluentes And Reticulate',
'Pediculosis Capitis', 'Pityriasis Rosea', 'Porokeratosis Actinic', 'Psoriasis',
'Tinea Corporis', 'Tinea Nigra', 'Tungiasis', 'actinic keratosis', 'dermatofibroma',
'nevus', 'pigmented benign keratosis', 'seborrheic keratosis', 'squamous cell carcinoma',
'vascular lesion'
]
# =======================================
# π Frontend Routes
# =======================================
@app.route("/")
def index():
return render_template("index.html")
@app.route("/upload")
def upload():
return render_template("upload.html")
@app.route("/result")
def result():
return render_template("result.html") # Notice: matches the filename "results.html" instead of "result.html"
# =======================================
# πΈ /analyze Route
# =======================================
@app.route('/analyze', methods=['POST'])
def analyze():
if 'image' not in request.files:
return jsonify({"error": "No image uploaded"}), 400
image_file = request.files['image']
image = Image.open(image_file.stream).convert("RGB")
inputs = processor(images=image, return_tensors="pt")
with torch.no_grad():
logits = image_model(**inputs).logits
probs = torch.softmax(logits, dim=-1)[0]
top_idx = torch.argmax(probs).item()
top_conf = probs[top_idx].item()
prediction = class_names[top_idx]
top_conditions = sorted(
zip(class_names, probs.tolist()),
key=lambda x: x[1],
reverse=True
)[:5]
return jsonify({
"prediction": prediction,
"confidence": round(top_conf, 4),
"topConditions": [(name, round(prob, 4)) for name, prob in top_conditions],
"description": f"{prediction} is a skin condition. Please consult a medical professional.",
"recommendations": [
"Take a clearer image if unsure.",
"Consider visiting a dermatologist.",
"Avoid self-diagnosis or self-treatment."
]
})
# =======================================
# π¬ /ask Route
# =======================================
@app.route('/ask', methods=['POST'])
def ask():
data = request.json
question = data.get("question", "")
condition = data.get("condition", "")
if not question:
return jsonify({"answer": "Please ask a valid question."}), 400
messages = [
{
"role": "user",
"content": f"A user may have {condition}. They asked: '{question}'. Respond like a helpful AI medical assistant."
}
]
try:
response = client.chat_completion(
messages=messages,
max_tokens=200
)
answer = response.choices[0]["message"]["content"]
return jsonify({"answer": answer.strip()})
except Exception as e:
return jsonify({"answer": f"Error communicating with Hugging Face: {e}"}), 500
# Add route for placeholder images if needed
@app.route('/api/placeholder/<width>/<height>')
def placeholder(width, height):
# This is a simple implementation - you might want to generate an actual placeholder image
# For now, we'll just serve a static placeholder
return send_from_directory('static/images', 'placeholder.jpg')
if __name__ == '__main__':
app.run(debug=True) |