stephenebert commited on
Commit
7667eb1
·
verified ·
1 Parent(s): 6aba4b8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +11 -17
app.py CHANGED
@@ -1,14 +1,16 @@
1
  from __future__ import annotations
2
 
3
- # FastAPI REST API + Gradio Interface mounted at /ui
4
  # Endpoints:
5
  # GET /healthz
6
  # POST /upload -> {filename, caption, tags}
7
  # UI:
8
- # /ui (upload image, choose top_k, see caption + tags)
 
 
9
 
10
  from fastapi import FastAPI, File, HTTPException, Query, UploadFile
11
- from fastapi.responses import JSONResponse, RedirectResponse
12
  from pydantic import BaseModel
13
  from typing import List
14
  from pathlib import Path
@@ -18,7 +20,7 @@ import io
18
  import gradio as gr
19
  from tagger import tag_pil_image # returns (caption: str, tags: List[str])
20
 
21
- app = FastAPI(title="Image Tagger API", version="0.4.2")
22
 
23
  # ---------- Pydantic model ----------
24
  class TagOut(BaseModel):
@@ -26,12 +28,7 @@ class TagOut(BaseModel):
26
  caption: str
27
  tags: List[str]
28
 
29
- # ---------- Basic routes ----------
30
- @app.get("/", include_in_schema=False)
31
- def root_redirect():
32
- # Send users to the nicer UI
33
- return RedirectResponse(url="/ui", status_code=302)
34
-
35
  @app.get("/healthz")
36
  def healthz():
37
  return {"ok": True}
@@ -42,13 +39,11 @@ async def upload(
42
  file: UploadFile = File(...),
43
  top_k: int = Query(5, ge=1, le=20, description="Max number of tags"),
44
  ):
45
- # MIME guard
46
  if file.content_type not in {"image/png", "image/jpeg", "image/webp"}:
47
  raise HTTPException(
48
  status_code=415, detail="Only PNG, JPEG, or WebP images are supported"
49
  )
50
 
51
- # Decode image
52
  try:
53
  data = await file.read()
54
  img = Image.open(io.BytesIO(data)).convert("RGB")
@@ -57,7 +52,6 @@ async def upload(
57
 
58
  stem = Path(file.filename).stem or "upload"
59
 
60
- # Tag
61
  try:
62
  caption, tags = tag_pil_image(img, stem, top_k=top_k)
63
  except Exception as e:
@@ -65,7 +59,7 @@ async def upload(
65
 
66
  return JSONResponse({"filename": file.filename, "caption": caption, "tags": tags})
67
 
68
- # ---------- Gradio Interface (mounted at /ui) ----------
69
  def _ui_tag(image: Image.Image, top_k: int):
70
  if image is None:
71
  return "", ""
@@ -82,11 +76,11 @@ demo = gr.Interface(
82
  gr.Textbox(label="Caption", lines=2),
83
  gr.Textbox(label="Tags (comma-separated)", lines=2),
84
  ],
85
- allow_flagging="never",
86
  title="Image Tagger",
87
  description="Upload an image to get a caption and top-k tags. Programmatic API at /docs.",
88
  )
89
 
90
- # Mount Gradio on the same FastAPI app
91
- app = gr.mount_gradio_app(app, demo, path="/ui")
92
 
 
1
  from __future__ import annotations
2
 
3
+ # FastAPI REST API + Gradio UI at /
4
  # Endpoints:
5
  # GET /healthz
6
  # POST /upload -> {filename, caption, tags}
7
  # UI:
8
+ # / (upload image, choose top_k, see caption + tags)
9
+ # Docs:
10
+ # /docs
11
 
12
  from fastapi import FastAPI, File, HTTPException, Query, UploadFile
13
+ from fastapi.responses import JSONResponse
14
  from pydantic import BaseModel
15
  from typing import List
16
  from pathlib import Path
 
20
  import gradio as gr
21
  from tagger import tag_pil_image # returns (caption: str, tags: List[str])
22
 
23
+ app = FastAPI(title="Image Tagger API", version="0.4.3")
24
 
25
  # ---------- Pydantic model ----------
26
  class TagOut(BaseModel):
 
28
  caption: str
29
  tags: List[str]
30
 
31
+ # ---------- Health ----------
 
 
 
 
 
32
  @app.get("/healthz")
33
  def healthz():
34
  return {"ok": True}
 
39
  file: UploadFile = File(...),
40
  top_k: int = Query(5, ge=1, le=20, description="Max number of tags"),
41
  ):
 
42
  if file.content_type not in {"image/png", "image/jpeg", "image/webp"}:
43
  raise HTTPException(
44
  status_code=415, detail="Only PNG, JPEG, or WebP images are supported"
45
  )
46
 
 
47
  try:
48
  data = await file.read()
49
  img = Image.open(io.BytesIO(data)).convert("RGB")
 
52
 
53
  stem = Path(file.filename).stem or "upload"
54
 
 
55
  try:
56
  caption, tags = tag_pil_image(img, stem, top_k=top_k)
57
  except Exception as e:
 
59
 
60
  return JSONResponse({"filename": file.filename, "caption": caption, "tags": tags})
61
 
62
+ # ---------- Gradio UI at root ----------
63
  def _ui_tag(image: Image.Image, top_k: int):
64
  if image is None:
65
  return "", ""
 
76
  gr.Textbox(label="Caption", lines=2),
77
  gr.Textbox(label="Tags (comma-separated)", lines=2),
78
  ],
79
+ flagging_mode="never",
80
  title="Image Tagger",
81
  description="Upload an image to get a caption and top-k tags. Programmatic API at /docs.",
82
  )
83
 
84
+ # Mount Gradio on the same FastAPI app at root (/) to avoid redirects
85
+ app = gr.mount_gradio_app(app, demo, path="/")
86