Tantawi65 commited on
Commit
900e15e
·
1 Parent(s): 84fdd79

Revert: Back to original working app structure

Browse files
Files changed (2) hide show
  1. Dockerfile +1 -1
  2. main.py +0 -177
Dockerfile CHANGED
@@ -24,4 +24,4 @@ ENV PYTHONPATH=/code
24
  ENV TMPDIR=/tmp
25
 
26
  # Command to run the application
27
- CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]
 
24
  ENV TMPDIR=/tmp
25
 
26
  # Command to run the application
27
+ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "7860"]
main.py DELETED
@@ -1,177 +0,0 @@
1
- import shutil
2
- import os
3
- import uuid
4
- from fastapi import FastAPI, File, UploadFile, HTTPException
5
- from fastapi.responses import JSONResponse
6
- from fastapi.middleware.cors import CORSMiddleware
7
-
8
- # Embedded prediction function with model loading
9
- import sys
10
- import numpy as np
11
- import tensorflow as tf
12
- from tensorflow.keras.preprocessing import image
13
- from huggingface_hub import hf_hub_download
14
-
15
- # Model configuration
16
- MODEL_PATH = "app/model/efficientnetv2s.h5"
17
- REPO_ID = "Miguel764/efficientnetv2s-skin-cancer-classifier"
18
- FILENAME = "efficientnetv2s.h5"
19
- TEMPERATURE = 2.77
20
-
21
- class_names_mapping = {
22
- 0: "AKIEC",
23
- 1: "BCC",
24
- 2: "BKL",
25
- 3: "DF",
26
- 4: "MEL",
27
- 5: "NV",
28
- 6: "VASC"
29
- }
30
-
31
- full_names = {
32
- "AKIEC": "Actinic keratoses and intraepithelial carcinoma",
33
- "BCC": "Basal cell carcinoma",
34
- "BKL": "Benign keratosis-like lesions",
35
- "DF": "Dermatofibroma",
36
- "MEL": "Melanoma",
37
- "NV": "Melanocytic nevi",
38
- "VASC": "Vascular lesions"
39
- }
40
-
41
- # Global model variable
42
- model = None
43
-
44
- def load_model():
45
- global model
46
- try:
47
- if not os.path.exists(MODEL_PATH):
48
- print("Model not found locally. Downloading from Hugging Face...")
49
- os.makedirs(os.path.dirname(MODEL_PATH), exist_ok=True)
50
- hf_hub_download(
51
- repo_id=REPO_ID,
52
- filename=FILENAME,
53
- local_dir="app/model"
54
- )
55
- else:
56
- print("Model already exists locally.")
57
-
58
- print("Loading TensorFlow model...")
59
- model = tf.keras.models.load_model(MODEL_PATH)
60
- print("Model loaded successfully!")
61
- return model
62
- except Exception as e:
63
- print(f"Error loading model: {e}")
64
- return None
65
-
66
- def predict_image(image_path):
67
- global model
68
- try:
69
- if model is None:
70
- model = load_model()
71
- if model is None:
72
- return "Error: Model not loaded", 0.0, [{"label": "Error", "confidence": 0.0}]
73
-
74
- # Load and preprocess image
75
- img = image.load_img(image_path, target_size=(224, 224))
76
- img_array = image.img_to_array(img)
77
- img_array = np.expand_dims(img_array, axis=0)
78
- img_array = tf.keras.applications.imagenet_utils.preprocess_input(img_array)
79
-
80
- # Make prediction
81
- logits = model.predict(img_array)
82
- scaled_logits = logits / TEMPERATURE
83
- scaled_probs = tf.nn.softmax(scaled_logits).numpy()[0]
84
-
85
- class_idx = int(np.argmax(scaled_probs))
86
- top_label = full_names[class_names_mapping[class_idx]]
87
- top_confidence = float(scaled_probs[class_idx])
88
-
89
- all_predictions = [
90
- {"label": class_names_mapping[i], "confidence": float(pred)}
91
- for i, pred in enumerate(scaled_probs)
92
- ]
93
-
94
- return top_label, top_confidence, all_predictions
95
-
96
- except Exception as e:
97
- print(f"Prediction error: {e}")
98
- return f"Error: {str(e)}", 0.0, [{"label": "Error", "confidence": 0.0}]
99
-
100
- app = FastAPI(
101
- title="GP-Tea Skin Analysis API",
102
- description="AI-powered skin condition analysis service",
103
- version="1.0.0"
104
- )
105
-
106
- # Add CORS middleware
107
- app.add_middleware(
108
- CORSMiddleware,
109
- allow_origins=["*"],
110
- allow_credentials=True,
111
- allow_methods=["*"],
112
- allow_headers=["*"],
113
- )
114
-
115
- # Create uploads directory in tmp (writable in containers)
116
- import tempfile
117
- UPLOAD_DIR = tempfile.mkdtemp()
118
- os.makedirs(UPLOAD_DIR, exist_ok=True)
119
-
120
- @app.get("/")
121
- async def root():
122
- return {"message": "GP-Tea Skin Analysis API", "status": "running"}
123
-
124
- @app.get("/health")
125
- async def health_check():
126
- return {"status": "healthy", "service": "gp-tea-skin-analysis"}
127
-
128
- @app.post("/analyze_image")
129
- async def analyze_image(file: UploadFile = File(...)):
130
- """Analyze skin image for medical conditions"""
131
- try:
132
- if not file.content_type or not file.content_type.startswith('image/'):
133
- raise HTTPException(status_code=400, detail="File must be an image")
134
-
135
- unique_filename = f"{uuid.uuid4().hex}_{file.filename}"
136
- file_path = os.path.join(UPLOAD_DIR, unique_filename)
137
-
138
- with open(file_path, "wb") as buffer:
139
- shutil.copyfileobj(file.file, buffer)
140
-
141
- label, confidence, all_predictions = predict_image(file_path)
142
-
143
- # Clean up uploaded file
144
- if os.path.exists(file_path):
145
- os.remove(file_path)
146
-
147
- formatted_predictions = []
148
- for pred in all_predictions:
149
- formatted_predictions.append({
150
- "label": pred["label"],
151
- "confidence": float(pred["confidence"]),
152
- "confidence_percent": f"{pred['confidence'] * 100:.2f}%"
153
- })
154
-
155
- return JSONResponse(
156
- status_code=200,
157
- content={
158
- "success": True,
159
- "prediction": {
160
- "top_prediction": {
161
- "label": label,
162
- "confidence": float(confidence),
163
- "confidence_percent": f"{confidence * 100:.2f}%"
164
- },
165
- "all_predictions": formatted_predictions
166
- }
167
- }
168
- )
169
-
170
- except Exception as e:
171
- if 'file_path' in locals() and os.path.exists(file_path):
172
- os.remove(file_path)
173
- raise HTTPException(status_code=500, detail=f"Classification failed: {str(e)}")
174
-
175
- if __name__ == "__main__":
176
- import uvicorn
177
- uvicorn.run(app, host="0.0.0.0", port=7860)