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

Update app_working_api.py

Browse files
Files changed (1) hide show
  1. app_working_api.py +28 -15
app_working_api.py CHANGED
@@ -2,12 +2,13 @@ import io
2
  import asyncio
3
  import threading
4
  import time
5
- from fastapi import FastAPI, File, UploadFile
6
- from fastapi.responses import JSONResponse, HTMLResponse
7
  from PIL import Image
8
  import torch
9
  from transformers import AutoProcessor, AutoModelForCausalLM
10
  import requests
 
11
 
12
  # ---------------------------------------------------
13
  # FastAPI App
@@ -21,9 +22,10 @@ processor = None
21
  model = None
22
  model_lock = asyncio.Lock()
23
 
 
 
24
 
25
  async def load_model():
26
- """Load Florence model only when first needed."""
27
  global processor, model
28
 
29
  if model is None:
@@ -38,7 +40,6 @@ async def load_model():
38
 
39
 
40
  def run_caption(image: Image.Image) -> str:
41
- """Perform caption generation."""
42
  inputs = processor(
43
  text="<MORE_DETAILED_CAPTION>",
44
  images=image,
@@ -64,30 +65,41 @@ def run_caption(image: Image.Image) -> str:
64
 
65
 
66
  # ---------------------------------------------------
67
- # API Endpoint
68
  # ---------------------------------------------------
69
- @app.post("/img2caption")
70
- async def img2caption(file: UploadFile = File(...)):
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  try:
72
- # Ensure model is loaded
73
  async with model_lock:
74
  await load_model()
75
 
76
- # Read and convert image
77
  data = await file.read()
78
  image = Image.open(io.BytesIO(data)).convert("RGB")
79
 
80
- # Caption
81
  caption = run_caption(image)
82
 
83
- return {"caption": caption}
 
84
 
85
  except Exception as e:
86
- return JSONResponse({"error": str(e)}, status_code=500)
87
 
88
 
89
  # ---------------------------------------------------
90
- # Simple HTML UI
91
  # ---------------------------------------------------
92
  @app.get("/", response_class=HTMLResponse)
93
  def ui():
@@ -146,8 +158,8 @@ def ui():
146
  method: "POST",
147
  body: form
148
  });
149
- const data = await res.json();
150
- captionBox.innerHTML = data.caption || data.error;
151
  }
152
  </script>
153
  </body>
@@ -158,6 +170,7 @@ def ui():
158
  def keep_alive():
159
  pass
160
 
 
161
  if __name__ == "__main__":
162
  import uvicorn
163
  print("🚀 Launching Fast img2caption API")
 
2
  import asyncio
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
10
  import requests
11
+ import os
12
 
13
  # ---------------------------------------------------
14
  # FastAPI App
 
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():
 
158
  method: "POST",
159
  body: form
160
  });
161
+ const text = await res.text();
162
+ captionBox.innerHTML = text;
163
  }
164
  </script>
165
  </body>
 
170
  def keep_alive():
171
  pass
172
 
173
+
174
  if __name__ == "__main__":
175
  import uvicorn
176
  print("🚀 Launching Fast img2caption API")