"""호가(orderbook) API — KIS 10단계 호가 스냅샷. 장중에 호출하면 호가 + 잔량 + 현재가가 한 번의 KIS 호출로 따라온다. 실시간 ws 가 아니라 폴링 친화 (프론트가 5~10s 주기로 재호출) 설계 — 표시 전용. """ from __future__ import annotations from fastapi import APIRouter, HTTPException from sqlalchemy import text from app.db.connection import get_engine from app.fetch.kis import SkippedMissingKey, fetch_orderbook router = APIRouter(prefix="/api/orderbook", tags=["orderbook"]) @router.get("/{code}") def get_orderbook(code: str) -> dict: """code 의 10단계 호가 스냅샷. - symbols 에 없는 코드는 404. - KIS 키 미설정이면 status="skipped_missing_key" + 빈 호가 (프론트에서 안내). - KIS 호출 실패는 502. """ eng = get_engine() with eng.connect() as conn: sym = conn.execute( text("SELECT code, name, market FROM symbols WHERE code = :c"), {"c": code}, ).first() if not sym: raise HTTPException(status_code=404, detail=f"unknown code: {code}") try: snap = fetch_orderbook(code) except SkippedMissingKey: return { "code": sym[0], "name": sym[1], "market": sym[2], "status": "skipped_missing_key", "ts": None, "current": None, "prev_close_diff": None, "prev_close_pct": None, "asks": [], "bids": [], "ask_total": 0, "bid_total": 0, } except Exception as exc: # noqa: BLE001 raise HTTPException(status_code=502, detail=f"kis orderbook failed: {exc}") from exc return { "code": sym[0], "name": sym[1], "market": sym[2], "status": "ok", **snap, }