Download app/api.py from klee9/gdg-test: direct link, hf CLI and curl.
- Browser
- Download file 1.8 kB
-
https://huggingface.co/spaces/klee9/gdg-test/resolve/main/app/api.py
- Command line
-
hf download hf://spaces/klee9/gdg-test/app/api.py
-
curl -L -o api.py https://huggingface.co/spaces/klee9/gdg-test/resolve/main/app/api.py
1.8 kB
| import os | |
| import requests | |
| from typing import List | |
| from fastapi import FastAPI | |
| from pydantic import BaseModel, Field | |
| from app.clients.gemma_client import GemmaClient | |
| from app.services.step1_extract import MenuExtractor | |
| from app.services.step2_rank import MenuRanker | |
| from app.utils.image_io import load_image_from_url | |
| app = FastAPI(title="Menu AI API", version="0.1") | |
| # --- singletons --- | |
| gemma = GemmaClient( | |
| api_key=os.getenv("GOOGLE_API_KEY"), | |
| model=os.getenv("MODEL_ID", "gemma-3-4b-it"), | |
| ) | |
| extractor = MenuExtractor(gemma) | |
| ranker = MenuRanker(gemma, uncertainty_penalty=40) | |
| class RankRequest(BaseModel): | |
| image_url: str = Field(..., description="메뉴판 이미지 URL") | |
| avoid: List[str] = Field(default_factory=list, description="기피 재료 리스트") | |
| lang: str = Field('ko') | |
| class RankResponse(BaseModel): | |
| items_extracted: List[str] | |
| items: list | |
| best: dict | |
| def health(): | |
| return {"ok": True} | |
| def rank(req: RankRequest): | |
| # 1) URL에서 이미지 다운로드 | |
| data, mime = load_image_from_url(req.image_url) | |
| # 2) Gemma 입력 Part 만들기 | |
| img_part = gemma.image_part_from_bytes(data, mime) | |
| # 3) Step1: 메뉴 추출 | |
| items = extractor.extract(img_part) | |
| # 4) Step2: 랭킹 | |
| ranked = ranker.rank(items, req.avoid) | |
| # 5) Step3: Presigned URL로 이미지 업로드 | |
| bbox_img = None | |
| headers = {"Content-Type": mime or "application/octet-stream"} | |
| requests.put(req.presigned_url, data=bbox_img, headers=headers, timeout=10) | |
| # 5) 백엔드에 넘길 최종 응답 | |
| return { | |
| "items_extracted": items, | |
| "items": ranked["items"], # score 내림차순 정렬된 리스트 | |
| "best": ranked["best"], | |
| } | |