videopix commited on
Commit
b53989e
·
verified ·
1 Parent(s): 735c9b7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +14 -18
app.py CHANGED
@@ -3,7 +3,7 @@ import asyncio
3
  import threading
4
  import time
5
  from fastapi import FastAPI, File, UploadFile, Header
6
- from fastapi.responses import JSONResponse, HTMLResponse
7
  from PIL import Image
8
  import torch
9
  from transformers import AutoProcessor, AutoModelForCausalLM
@@ -22,11 +22,10 @@ processor = None
22
  model = None
23
  model_lock = asyncio.Lock()
24
 
25
- # Hugging Face token stored in HF Secrets
26
  HF_TOKEN = os.getenv("img2caption")
27
 
28
  async def load_model():
29
- """Load Florence model only when first needed."""
30
  global processor, model
31
 
32
  if model is None:
@@ -41,7 +40,6 @@ async def load_model():
41
 
42
 
43
  def run_caption(image: Image.Image) -> str:
44
- """Perform caption generation."""
45
  inputs = processor(
46
  text="<MORE_DETAILED_CAPTION>",
47
  images=image,
@@ -67,43 +65,41 @@ def run_caption(image: Image.Image) -> str:
67
 
68
 
69
  # ---------------------------------------------------
70
- # API Endpoint (Token enforced only when app sends a token)
71
  # ---------------------------------------------------
72
- @app.post("/img2caption")
73
  async def img2caption(
74
  file: UploadFile = File(...),
75
  authorization: str = Header(None)
76
  ):
77
- # Apps must send token → enforce check
78
- # UI sends no token → skip check → allow
79
  if authorization is not None:
80
  if not authorization.startswith("Bearer "):
81
- return JSONResponse({"error": "Invalid token format"}, status_code=403)
82
 
83
  token = authorization.replace("Bearer ", "").strip()
84
  if token != HF_TOKEN:
85
- return JSONResponse({"error": "Invalid token"}, status_code=403)
86
 
87
  try:
88
- # Ensure model is loaded
89
  async with model_lock:
90
  await load_model()
91
 
92
- # Read and convert image
93
  data = await file.read()
94
  image = Image.open(io.BytesIO(data)).convert("RGB")
95
 
96
- # Caption
97
  caption = run_caption(image)
98
 
99
- return {"caption": caption}
 
100
 
101
  except Exception as e:
102
- return JSONResponse({"error": str(e)}, status_code=500)
103
 
104
 
105
  # ---------------------------------------------------
106
- # Simple HTML UI (NO token required)
107
  # ---------------------------------------------------
108
  @app.get("/", response_class=HTMLResponse)
109
  def ui():
@@ -173,8 +169,8 @@ def ui():
173
  body: form
174
  });
175
 
176
- const data = await res.json();
177
- captionBox.innerHTML = data.caption || data.error;
178
  }
179
  </script>
180
 
 
3
  import threading
4
  import time
5
  from fastapi import FastAPI, File, UploadFile, Header
6
+ from fastapi.responses import JSONResponse, HTMLResponse, PlainTextResponse
7
  from PIL import Image
8
  import torch
9
  from transformers import AutoProcessor, AutoModelForCausalLM
 
22
  model = None
23
  model_lock = asyncio.Lock()
24
 
25
+ # Hugging Face token stored in Space secrets
26
  HF_TOKEN = os.getenv("img2caption")
27
 
28
  async def load_model():
 
29
  global processor, model
30
 
31
  if model is None:
 
40
 
41
 
42
  def run_caption(image: Image.Image) -> str:
 
43
  inputs = processor(
44
  text="<MORE_DETAILED_CAPTION>",
45
  images=image,
 
65
 
66
 
67
  # ---------------------------------------------------
68
+ # API Endpoint (Protected only if token is sent)
69
  # ---------------------------------------------------
70
+ @app.post("/img2caption", response_class=PlainTextResponse)
71
  async def img2caption(
72
  file: UploadFile = File(...),
73
  authorization: str = Header(None)
74
  ):
75
+
76
+ # If app sends a token → validate it
77
  if authorization is not None:
78
  if not authorization.startswith("Bearer "):
79
+ return PlainTextResponse("Invalid token format", status_code=403)
80
 
81
  token = authorization.replace("Bearer ", "").strip()
82
  if token != HF_TOKEN:
83
+ return PlainTextResponse("Invalid token", status_code=403)
84
 
85
  try:
 
86
  async with model_lock:
87
  await load_model()
88
 
 
89
  data = await file.read()
90
  image = Image.open(io.BytesIO(data)).convert("RGB")
91
 
 
92
  caption = run_caption(image)
93
 
94
+ # Return ONLY the caption string, no JSON
95
+ return caption
96
 
97
  except Exception as e:
98
+ return PlainTextResponse(f"Error: {str(e)}", status_code=500)
99
 
100
 
101
  # ---------------------------------------------------
102
+ # Simple HTML UI (no token required)
103
  # ---------------------------------------------------
104
  @app.get("/", response_class=HTMLResponse)
105
  def ui():
 
169
  body: form
170
  });
171
 
172
+ const text = await res.text();
173
+ captionBox.innerHTML = text;
174
  }
175
  </script>
176