khushalcodiste commited on
Commit
c54acdc
·
1 Parent(s): 75d7116

fix: added

Browse files
Files changed (2) hide show
  1. README.md +4 -1
  2. app/main.py +13 -1
README.md CHANGED
@@ -11,6 +11,8 @@ app_port: 7860
11
 
12
  FastAPI service for `Salesforce/blip-image-captioning-large`, packaged for Hugging Face Docker Spaces.
13
 
 
 
14
  ## Endpoints
15
 
16
  - `GET /health`
@@ -20,6 +22,7 @@ FastAPI service for `Salesforce/blip-image-captioning-large`, packaged for Huggi
20
 
21
  ```bash
22
  curl -X POST "http://localhost:7860/caption" \
 
23
  -F "image=@example.jpg" \
24
  -F "min_new_tokens=5" \
25
  -F "max_new_tokens=20"
@@ -29,5 +32,5 @@ curl -X POST "http://localhost:7860/caption" \
29
 
30
  ```bash
31
  docker build -t blip-large-api .
32
- docker run -p 7860:7860 blip-large-api
33
  ```
 
11
 
12
  FastAPI service for `Salesforce/blip-image-captioning-large`, packaged for Hugging Face Docker Spaces.
13
 
14
+ Set a Hugging Face Space secret named `API_KEY` to protect the caption endpoint.
15
+
16
  ## Endpoints
17
 
18
  - `GET /health`
 
22
 
23
  ```bash
24
  curl -X POST "http://localhost:7860/caption" \
25
+ -H "x-api-key: your-secret-key" \
26
  -F "image=@example.jpg" \
27
  -F "min_new_tokens=5" \
28
  -F "max_new_tokens=20"
 
32
 
33
  ```bash
34
  docker build -t blip-large-api .
35
+ docker run -p 7860:7860 -e API_KEY=your-secret-key blip-large-api
36
  ```
app/main.py CHANGED
@@ -3,14 +3,17 @@ import os
3
  import time
4
  from contextlib import asynccontextmanager
5
 
6
- from fastapi import FastAPI, File, Form, HTTPException, UploadFile
7
  from fastapi.responses import JSONResponse
 
8
  from PIL import Image, UnidentifiedImageError
9
  from transformers import AutoTokenizer, BlipForConditionalGeneration, BlipImageProcessor, BlipProcessor
10
 
11
  Image.MAX_IMAGE_PIXELS = None
12
 
13
  MODEL_ID = os.getenv("MODEL_ID", "Salesforce/blip-image-captioning-large")
 
 
14
  USE_FAST_PROCESSOR = os.getenv("USE_FAST_PROCESSOR", "true").strip().lower() in {
15
  "1",
16
  "true",
@@ -21,6 +24,7 @@ MAX_IMAGE_SIZE = (128,128)
21
 
22
  processor: BlipProcessor | None = None
23
  model: BlipForConditionalGeneration | None = None
 
24
 
25
 
26
  def load_model() -> None:
@@ -33,6 +37,13 @@ def load_model() -> None:
33
  model = BlipForConditionalGeneration.from_pretrained(MODEL_ID)
34
 
35
 
 
 
 
 
 
 
 
36
  def generate_caption(image_bytes: bytes, min_new_tokens: int, max_new_tokens: int) -> str:
37
  if processor is None or model is None:
38
  raise RuntimeError("Model is not loaded.")
@@ -85,6 +96,7 @@ async def health() -> dict[str, str]:
85
 
86
  @app.post("/caption")
87
  async def caption_image(
 
88
  image: UploadFile = File(...),
89
  min_new_tokens: int = Form(5),
90
  max_new_tokens: int = Form(20),
 
3
  import time
4
  from contextlib import asynccontextmanager
5
 
6
+ from fastapi import FastAPI, File, Form, HTTPException, Security, UploadFile
7
  from fastapi.responses import JSONResponse
8
+ from fastapi.security import APIKeyHeader
9
  from PIL import Image, UnidentifiedImageError
10
  from transformers import AutoTokenizer, BlipForConditionalGeneration, BlipImageProcessor, BlipProcessor
11
 
12
  Image.MAX_IMAGE_PIXELS = None
13
 
14
  MODEL_ID = os.getenv("MODEL_ID", "Salesforce/blip-image-captioning-large")
15
+ API_KEY = os.getenv("API_KEY")
16
+ API_KEY_HEADER_NAME = os.getenv("API_KEY_HEADER_NAME", "x-api-key")
17
  USE_FAST_PROCESSOR = os.getenv("USE_FAST_PROCESSOR", "true").strip().lower() in {
18
  "1",
19
  "true",
 
24
 
25
  processor: BlipProcessor | None = None
26
  model: BlipForConditionalGeneration | None = None
27
+ api_key_header = APIKeyHeader(name=API_KEY_HEADER_NAME, auto_error=False)
28
 
29
 
30
  def load_model() -> None:
 
37
  model = BlipForConditionalGeneration.from_pretrained(MODEL_ID)
38
 
39
 
40
+ def verify_api_key(api_key: str | None = Security(api_key_header)) -> None:
41
+ if not API_KEY:
42
+ raise RuntimeError("API_KEY environment variable is required.")
43
+ if api_key != API_KEY:
44
+ raise HTTPException(status_code=401, detail="Invalid or missing API key.")
45
+
46
+
47
  def generate_caption(image_bytes: bytes, min_new_tokens: int, max_new_tokens: int) -> str:
48
  if processor is None or model is None:
49
  raise RuntimeError("Model is not loaded.")
 
96
 
97
  @app.post("/caption")
98
  async def caption_image(
99
+ _: None = Security(verify_api_key),
100
  image: UploadFile = File(...),
101
  min_new_tokens: int = Form(5),
102
  max_new_tokens: int = Form(20),