stephenebert commited on
Commit
e7d0635
·
verified ·
1 Parent(s): a184b98

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +4 -37
app.py CHANGED
@@ -1,37 +1,28 @@
1
  from __future__ import annotations
2
-
3
- # FastAPI app exposing:
4
- # GET /healthz -> {"ok": true}
5
- # GET / -> tiny upload form (links to /docs)
6
- # POST /upload -> {"filename","caption","tags"}
7
-
8
  from fastapi import FastAPI, File, HTTPException, Query, UploadFile
9
  from fastapi.responses import HTMLResponse, JSONResponse
10
  from pydantic import BaseModel
11
  from typing import List
12
  from pathlib import Path
13
  from PIL import Image
14
- import io, json
15
 
16
- from tagger import tag_pil_image, CAP_TAG_DIR # tagger writes ./data/<stem>.json
17
 
18
  app = FastAPI(title="Image Tagger API", version="0.3.0")
19
 
20
-
21
  class TagOut(BaseModel):
22
  filename: str
23
  caption: str
24
  tags: List[str]
25
 
26
-
27
  @app.get("/", response_class=HTMLResponse)
28
  def home() -> str:
29
- # Simple HTML so you can upload from the root page
30
  return """
31
  <html><head><meta charset="utf-8"><title>Image Tagger API</title></head>
32
  <body style="font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,sans-serif;max-width:720px;margin:40px auto;padding:0 16px">
33
  <h2>Image Tagger API</h2>
34
- <p>Use <a href="/docs">/docs</a> for full Swagger UI, or upload here:</p>
35
  <form action="/upload" method="post" enctype="multipart/form-data" style="display:grid;gap:12px">
36
  <input type="file" name="file" accept="image/png,image/jpeg,image/webp" required />
37
  <label>top_k:
@@ -42,20 +33,14 @@ def home() -> str:
42
  </body></html>
43
  """
44
 
45
-
46
  @app.get("/healthz")
47
  def healthz():
48
  return {"ok": True}
49
 
50
-
51
  @app.post("/upload", response_model=TagOut)
52
  async def upload(
53
  file: UploadFile = File(...),
54
  top_k: int = Query(5, ge=1, le=20, description="Max number of tags"),
55
- # kept for backward compatibility with earlier UI; tagger ignores them
56
- nouns: bool = Query(True, description="(ignored)"),
57
- adjs: bool = Query(True, description="(ignored)"),
58
- verbs: bool = Query(True, description="(ignored)"),
59
  ):
60
  if file.content_type not in {"image/png", "image/jpeg", "image/webp"}:
61
  raise HTTPException(status_code=415, detail="Only PNG, JPEG, or WebP images are supported")
@@ -67,29 +52,11 @@ async def upload(
67
  except Exception:
68
  raise HTTPException(status_code=400, detail="Could not decode image")
69
 
70
- # Create a sensible stem for sidecar filename
71
  stem = Path(file.filename).stem or "upload"
72
 
73
- # Generate tags (and sidecar JSON with caption written by tagger.py)
74
  try:
75
- tags = tag_pil_image(
76
- img,
77
- stem,
78
- top_k=top_k,
79
- keep_nouns=nouns,
80
- keep_adjs=adjs,
81
- keep_verbs=verbs,
82
- )
83
  except Exception as e:
84
  raise HTTPException(status_code=500, detail=f"Tagging failed: {e}")
85
 
86
- # Read caption from the sidecar if present
87
- caption = ""
88
- sidecar = CAP_TAG_DIR / f"{stem}.json"
89
- if sidecar.exists():
90
- try:
91
- caption = json.loads(sidecar.read_text()).get("caption", "")
92
- except Exception:
93
- caption = ""
94
-
95
  return JSONResponse({"filename": file.filename, "caption": caption, "tags": tags})
 
1
  from __future__ import annotations
 
 
 
 
 
 
2
  from fastapi import FastAPI, File, HTTPException, Query, UploadFile
3
  from fastapi.responses import HTMLResponse, JSONResponse
4
  from pydantic import BaseModel
5
  from typing import List
6
  from pathlib import Path
7
  from PIL import Image
8
+ import io
9
 
10
+ from tagger import tag_pil_image # returns (caption, tags)
11
 
12
  app = FastAPI(title="Image Tagger API", version="0.3.0")
13
 
 
14
  class TagOut(BaseModel):
15
  filename: str
16
  caption: str
17
  tags: List[str]
18
 
 
19
  @app.get("/", response_class=HTMLResponse)
20
  def home() -> str:
 
21
  return """
22
  <html><head><meta charset="utf-8"><title>Image Tagger API</title></head>
23
  <body style="font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,sans-serif;max-width:720px;margin:40px auto;padding:0 16px">
24
  <h2>Image Tagger API</h2>
25
+ <p>Use <a href="/docs">/docs</a> for Swagger, or upload here:</p>
26
  <form action="/upload" method="post" enctype="multipart/form-data" style="display:grid;gap:12px">
27
  <input type="file" name="file" accept="image/png,image/jpeg,image/webp" required />
28
  <label>top_k:
 
33
  </body></html>
34
  """
35
 
 
36
  @app.get("/healthz")
37
  def healthz():
38
  return {"ok": True}
39
 
 
40
  @app.post("/upload", response_model=TagOut)
41
  async def upload(
42
  file: UploadFile = File(...),
43
  top_k: int = Query(5, ge=1, le=20, description="Max number of tags"),
 
 
 
 
44
  ):
45
  if file.content_type not in {"image/png", "image/jpeg", "image/webp"}:
46
  raise HTTPException(status_code=415, detail="Only PNG, JPEG, or WebP images are supported")
 
52
  except Exception:
53
  raise HTTPException(status_code=400, detail="Could not decode image")
54
 
 
55
  stem = Path(file.filename).stem or "upload"
56
 
 
57
  try:
58
+ caption, tags = tag_pil_image(img, stem, top_k=top_k)
 
 
 
 
 
 
 
59
  except Exception as e:
60
  raise HTTPException(status_code=500, detail=f"Tagging failed: {e}")
61
 
 
 
 
 
 
 
 
 
 
62
  return JSONResponse({"filename": file.filename, "caption": caption, "tags": tags})