Fix the deployment space problem
Browse files- Dockerfile +12 -97
Dockerfile
CHANGED
|
@@ -1,121 +1,36 @@
|
|
| 1 |
FROM python:3.9-slim
|
| 2 |
|
| 3 |
-
# Create user to avoid permission issues on
|
| 4 |
RUN useradd -m -u 1000 user
|
|
|
|
| 5 |
WORKDIR /app
|
| 6 |
|
| 7 |
-
#
|
| 8 |
COPY requirements.txt .
|
| 9 |
RUN pip install --no-cache-dir -r requirements.txt
|
| 10 |
RUN pip install fastapi uvicorn python-multipart requests
|
| 11 |
|
| 12 |
-
#
|
| 13 |
-
# Copy only what backend needs (adjust these paths to your repo)
|
| 14 |
COPY app.py ./app.py
|
| 15 |
COPY scripts/ ./scripts/
|
| 16 |
COPY checkpoints/ ./checkpoints/
|
| 17 |
COPY data/ ./data/
|
| 18 |
|
| 19 |
-
#
|
| 20 |
-
|
| 21 |
-
COPY app.py api/app_gradio.py
|
| 22 |
-
RUN echo 'import os\n\
|
| 23 |
-
os.environ["MODEL_CHECKPOINT"] = "checkpoints/best_checkpoint.pth"\n\
|
| 24 |
-
os.environ["MULTI_TASK"] = "true"\n\
|
| 25 |
-
\n\
|
| 26 |
-
import sys\n\
|
| 27 |
-
from pathlib import Path\n\
|
| 28 |
-
sys.path.append(str(Path(__file__).parent.parent))\n\
|
| 29 |
-
\n\
|
| 30 |
-
from fastapi import FastAPI, File, UploadFile, HTTPException\n\
|
| 31 |
-
from fastapi.responses import JSONResponse, FileResponse, Response, HTMLResponse\n\
|
| 32 |
-
from fastapi.middleware.cors import CORSMiddleware\n\
|
| 33 |
-
from PIL import Image\n\
|
| 34 |
-
import io\n\
|
| 35 |
-
import json\n\
|
| 36 |
-
import math\n\
|
| 37 |
-
from datetime import datetime\n\
|
| 38 |
-
from scripts.inference import ModelInference\n\
|
| 39 |
-
\n\
|
| 40 |
-
app = FastAPI(title=\"Decade Classifier API\")\n\
|
| 41 |
-
\n\
|
| 42 |
-
app.add_middleware(\n\
|
| 43 |
-
CORSMiddleware,\n\
|
| 44 |
-
allow_origins=[\"*\"],\n\
|
| 45 |
-
allow_credentials=True,\n\
|
| 46 |
-
allow_methods=[\"*\"],\n\
|
| 47 |
-
allow_headers=[\"*\"],\n\
|
| 48 |
-
)\n\
|
| 49 |
-
\n\
|
| 50 |
-
model_inference = ModelInference(\n\
|
| 51 |
-
checkpoint_path=\"checkpoints/best_checkpoint.pth\",\n\
|
| 52 |
-
multi_task=True\n\
|
| 53 |
-
)\n\
|
| 54 |
-
\n\
|
| 55 |
-
@app.get(\"/\", response_class=HTMLResponse)\n\
|
| 56 |
-
async def root():\n\
|
| 57 |
-
html = Path(\"ui/index.html\").read_text(\"utf-8\")\n\
|
| 58 |
-
return HTMLResponse(html, headers={\"Cache-Control\": \"no-cache, no-store, must-revalidate\"})\n\
|
| 59 |
-
\n\
|
| 60 |
-
@app.get(\"/health\")\n\
|
| 61 |
-
async def health_check():\n\
|
| 62 |
-
return {\n\
|
| 63 |
-
\"status\": \"healthy\",\n\
|
| 64 |
-
\"model_loaded\": True,\n\
|
| 65 |
-
\"model_info\": {\"model_name\": \"resnet50\", \"multi_task\": True}\n\
|
| 66 |
-
}\n\
|
| 67 |
-
\n\
|
| 68 |
-
@app.get(\"/training_data\")\n\
|
| 69 |
-
async def get_training_data():\n\
|
| 70 |
-
with open(\"data/splits/train.json\", \"r\") as f:\n\
|
| 71 |
-
data = json.load(f)\n\
|
| 72 |
-
return {\"status\": \"success\", \"data\": data}\n\
|
| 73 |
-
\n\
|
| 74 |
-
@app.get(\"/proxy_image\")\n\
|
| 75 |
-
async def proxy_image(url: str):\n\
|
| 76 |
-
import requests\n\
|
| 77 |
-
try:\n\
|
| 78 |
-
if url.startswith(\"http://\"):\n\
|
| 79 |
-
https_url = url.replace(\"http://\", \"https://\")\n\
|
| 80 |
-
try:\n\
|
| 81 |
-
resp = requests.get(https_url, timeout=5)\n\
|
| 82 |
-
if resp.status_code == 200:\n\
|
| 83 |
-
return Response(content=resp.content, media_type=\"image/jpeg\")\n\
|
| 84 |
-
except:\n\
|
| 85 |
-
pass\n\
|
| 86 |
-
resp = requests.get(url, timeout=5)\n\
|
| 87 |
-
return Response(content=resp.content, media_type=\"image/jpeg\")\n\
|
| 88 |
-
except:\n\
|
| 89 |
-
return Response(status_code=404)\n\
|
| 90 |
-
\n\
|
| 91 |
-
@app.post(\"/predict\")\n\
|
| 92 |
-
async def predict(file: UploadFile = File(...)):\n\
|
| 93 |
-
contents = await file.read()\n\
|
| 94 |
-
image = Image.open(io.BytesIO(contents)).convert(\"RGB\")\n\
|
| 95 |
-
temp_path = Path(f\"temp_{datetime.now().timestamp()}.jpg\")\n\
|
| 96 |
-
image.save(temp_path)\n\
|
| 97 |
-
try:\n\
|
| 98 |
-
result = model_inference.predict_image(temp_path)\n\
|
| 99 |
-
return JSONResponse({\n\
|
| 100 |
-
\"status\": \"success\",\n\
|
| 101 |
-
\"predictions\": result,\n\
|
| 102 |
-
\"timestamp\": datetime.now().isoformat(),\n\
|
| 103 |
-
\"model_info\": {\"model_name\": \"resnet50\", \"multi_task\": True}\n\
|
| 104 |
-
})\n\
|
| 105 |
-
finally:\n\
|
| 106 |
-
if temp_path.exists():\n\
|
| 107 |
-
temp_path.unlink()\n\
|
| 108 |
-
' > api/app.py
|
| 109 |
|
| 110 |
-
#
|
| 111 |
RUN mkdir -p ui
|
| 112 |
COPY ui/ ./ui/
|
| 113 |
|
| 114 |
-
#
|
| 115 |
RUN echo "UI_BUILD_TS=$(date +%s)" > /app/ui/.buildtag
|
| 116 |
|
| 117 |
-
# Permissions &
|
| 118 |
RUN chown -R user:user /app
|
| 119 |
USER user
|
|
|
|
| 120 |
EXPOSE 7860
|
|
|
|
|
|
|
| 121 |
CMD ["uvicorn", "api.app:app", "--host", "0.0.0.0", "--port", "7860"]
|
|
|
|
| 1 |
FROM python:3.9-slim
|
| 2 |
|
| 3 |
+
# Create user to avoid permission issues on Hugging Face Spaces
|
| 4 |
RUN useradd -m -u 1000 user
|
| 5 |
+
|
| 6 |
WORKDIR /app
|
| 7 |
|
| 8 |
+
# === Install dependencies ===
|
| 9 |
COPY requirements.txt .
|
| 10 |
RUN pip install --no-cache-dir -r requirements.txt
|
| 11 |
RUN pip install fastapi uvicorn python-multipart requests
|
| 12 |
|
| 13 |
+
# === Copy backend (app + model + data) ===
|
|
|
|
| 14 |
COPY app.py ./app.py
|
| 15 |
COPY scripts/ ./scripts/
|
| 16 |
COPY checkpoints/ ./checkpoints/
|
| 17 |
COPY data/ ./data/
|
| 18 |
|
| 19 |
+
# === Copy API code ===
|
| 20 |
+
COPY api/app.py api/app.py
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
|
| 22 |
+
# === Copy UI last (so UI updates bust cache) ===
|
| 23 |
RUN mkdir -p ui
|
| 24 |
COPY ui/ ./ui/
|
| 25 |
|
| 26 |
+
# Optional cache-buster so HF rebuilds UI layer
|
| 27 |
RUN echo "UI_BUILD_TS=$(date +%s)" > /app/ui/.buildtag
|
| 28 |
|
| 29 |
+
# === Permissions & user ===
|
| 30 |
RUN chown -R user:user /app
|
| 31 |
USER user
|
| 32 |
+
|
| 33 |
EXPOSE 7860
|
| 34 |
+
|
| 35 |
+
# === Start FastAPI ===
|
| 36 |
CMD ["uvicorn", "api.app:app", "--host", "0.0.0.0", "--port", "7860"]
|