Image_Tagger / main.py
stephenebert's picture
Upload 5 files
cd3cf65 verified
from fastapi import FastAPI, File, HTTPException, Query, UploadFile
from fastapi.responses import JSONResponse
from pydantic import BaseModel
from pathlib import Path
from typing import List
import io, json
from PIL import Image
from .tagger import tag_pil_image
app = FastAPI(title="Image Tagger API", version="0.3.0")
class TagOut(BaseModel):
filename: str
caption: str
tags: List[str]
@app.get("/healthz")
def healthz():
return {"ok": True}
@app.post("/upload", response_model=TagOut)
async def upload(
file: UploadFile = File(..., description="PNG or JPEG image"),
top_k: int = Query(5, ge=1, le=20, description="Maximum number of tags"),
nouns: bool = Query(True, description="Include noun tags"),
adjs: bool = Query(True, description="Include adjective tags"),
verbs: bool = Query(True, description="Include verb tags"),
):
if file.content_type not in {"image/png", "image/jpeg"}:
raise HTTPException(415, "Only PNG or JPEG supported")
try:
data = await file.read()
img = Image.open(io.BytesIO(data)).convert("RGB")
except:
raise HTTPException(400, "Could not decode image")
stem = Path(file.filename).stem or "upload"
tags = tag_pil_image(
img,
stem,
top_k=top_k,
keep_nouns=nouns,
keep_adjs=adjs,
keep_verbs=verbs,
)
# pull the caption back out of the side-car JSON
caption = ""
meta = Path.home() / "Desktop" / "image_tags" / f"{stem}.json"
if meta.exists():
try:
caption = json.loads(meta.read_text())["caption"]
except:
pass
return JSONResponse(
{"filename": file.filename, "caption": caption, "tags": tags}
)