chenx906 commited on
Commit
e2af0c7
·
1 Parent(s): 13e7af1

Fix the deployment space problem

Browse files
Files changed (1) hide show
  1. api/app.py +36 -24
api/app.py CHANGED
@@ -1,29 +1,45 @@
1
  # api/app.py
 
 
 
 
 
2
  from fastapi import FastAPI, File, UploadFile
3
- from fastapi.responses import JSONResponse, FileResponse, Response
4
  from fastapi.middleware.cors import CORSMiddleware
5
- from pathlib import Path
6
  from PIL import Image
7
- import io, traceback, json
8
 
9
- app = FastAPI(title="VizRef API")
 
 
 
 
 
10
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  app.add_middleware(
12
  CORSMiddleware,
13
- allow_origins=["*"],
14
- allow_credentials=True,
15
- allow_methods=["*"],
16
- allow_headers=["*"],
17
  )
18
 
19
- # --- serve the frontend ---
20
  @app.get("/")
21
  def root():
22
- # robust absolute path to ui/index.html
23
- ui_path = Path(__file__).resolve().parent.parent / "ui" / "index.html"
24
- return FileResponse(str(ui_path))
25
 
26
- # --- API: health (frontend expects /api/health) ---
27
  @app.get("/api/health")
28
  def health_check():
29
  return {
@@ -32,14 +48,14 @@ def health_check():
32
  "model_info": {"model_name": "resnet50", "multi_task": True},
33
  }
34
 
35
- # --- API: training data (frontend expects /api/training_data) ---
36
  @app.get("/api/training_data")
37
  def get_training_data():
38
- with open("data/splits/train.json", "r") as f:
39
  data = json.load(f)
40
  return {"status": "success", "data": data}
41
 
42
- # --- API: proxy image (frontend calls /api/proxy_image) ---
43
  @app.get("/api/proxy_image")
44
  def proxy_image(url: str):
45
  import requests
@@ -57,9 +73,8 @@ def proxy_image(url: str):
57
  except:
58
  return Response(status_code=404)
59
 
60
- # --- API: predict (frontend posts to /api/predict) ---
61
  def _pythonify(obj):
62
- import numpy as np
63
  if isinstance(obj, dict):
64
  return {k: _pythonify(v) for k, v in obj.items()}
65
  if isinstance(obj, list):
@@ -72,23 +87,20 @@ def _pythonify(obj):
72
  return bool(obj)
73
  return obj
74
 
 
75
  @app.post("/api/predict")
76
  async def predict(file: UploadFile = File(...)):
77
  try:
78
  raw = await file.read()
79
- # decode image
80
  try:
81
  img = Image.open(io.BytesIO(raw)).convert("RGB")
82
  except Exception as e:
83
- return JSONResponse(
84
- {"status": "error", "message": f"Cannot read image: {e}"},
85
- status_code=400,
86
- )
87
 
88
  tmp = Path("/tmp/vizref_upload.jpg")
89
  img.save(tmp)
90
 
91
- # IMPORTANT: if your model loader expects CPU, ensure map_location="cpu" in your ModelInference
92
  result = model.predict_image(str(tmp))
93
 
94
  return JSONResponse({
 
1
  # api/app.py
2
+ import io
3
+ import json
4
+ import traceback
5
+ from pathlib import Path
6
+
7
  from fastapi import FastAPI, File, UploadFile
 
8
  from fastapi.middleware.cors import CORSMiddleware
9
+ from fastapi.responses import FileResponse, JSONResponse, Response
10
  from PIL import Image
 
11
 
12
+ import numpy as np
13
+ import sys
14
+
15
+ # make sure project root is importable (scripts/inference.py lives at repo root)
16
+ ROOT = Path(__file__).resolve().parent.parent
17
+ sys.path.append(str(ROOT))
18
 
19
+ # ---- YOUR ORIGINAL MODEL LOADER (unchanged in spirit) ----
20
+ from scripts.inference import ModelInference
21
+
22
+ # create model ONCE (like your original code)
23
+ # if your ModelInference supports map_location/device, set to CPU for Spaces
24
+ model = ModelInference(
25
+ checkpoint_path=str(ROOT / "checkpoints" / "best_checkpoint.pth"),
26
+ multi_task=True
27
+ )
28
+
29
+ # -------- FastAPI app & CORS ----------
30
+ app = FastAPI(title="VizRef API")
31
  app.add_middleware(
32
  CORSMiddleware,
33
+ allow_origins=["*"], allow_credentials=True,
34
+ allow_methods=["*"], allow_headers=["*"],
 
 
35
  )
36
 
37
+ # -------- Serve your UI ----------
38
  @app.get("/")
39
  def root():
40
+ return FileResponse(str(ROOT / "ui" / "index.html"))
 
 
41
 
42
+ # -------- API: health ----------
43
  @app.get("/api/health")
44
  def health_check():
45
  return {
 
48
  "model_info": {"model_name": "resnet50", "multi_task": True},
49
  }
50
 
51
+ # -------- API: training data ----------
52
  @app.get("/api/training_data")
53
  def get_training_data():
54
+ with open(ROOT / "data" / "splits" / "train.json", "r") as f:
55
  data = json.load(f)
56
  return {"status": "success", "data": data}
57
 
58
+ # -------- API: proxy image ----------
59
  @app.get("/api/proxy_image")
60
  def proxy_image(url: str):
61
  import requests
 
73
  except:
74
  return Response(status_code=404)
75
 
76
+ # --- helper to make numpy types JSON-safe ---
77
  def _pythonify(obj):
 
78
  if isinstance(obj, dict):
79
  return {k: _pythonify(v) for k, v in obj.items()}
80
  if isinstance(obj, list):
 
87
  return bool(obj)
88
  return obj
89
 
90
+ # -------- API: predict (your original logic, adapted to JSON) ----------
91
  @app.post("/api/predict")
92
  async def predict(file: UploadFile = File(...)):
93
  try:
94
  raw = await file.read()
 
95
  try:
96
  img = Image.open(io.BytesIO(raw)).convert("RGB")
97
  except Exception as e:
98
+ return JSONResponse({"status": "error", "message": f"Cannot read image: {e}"}, status_code=400)
 
 
 
99
 
100
  tmp = Path("/tmp/vizref_upload.jpg")
101
  img.save(tmp)
102
 
103
+ # your original call
104
  result = model.predict_image(str(tmp))
105
 
106
  return JSONResponse({