Coverage for view / web / routes / streaming.py: 100%
33 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-04 15:08 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-04 15:08 +0000
1"""
2실시간 현재가 구독 관리 API 엔드포인트.
3PriceSubscriptionService를 통해 UI에서 구독 요청/해지/현황 조회.
4"""
5from fastapi import APIRouter, HTTPException
6from pydantic import BaseModel
7from view.web.api_common import _get_ctx
8from services.price_subscription_service import SubscriptionPriority
10router = APIRouter()
13class SubscribeRequest(BaseModel):
14 code: str
15 reason: str # "ui_view", "watchlist" 등
18@router.post("/streaming/subscribe")
19async def subscribe_stock(req: SubscribeRequest):
20 """UI에서 특정 종목 실시간 가격 구독 요청."""
21 ctx = _get_ctx()
22 svc = getattr(ctx, "price_subscription_service", None)
23 if not svc:
24 raise HTTPException(status_code=503, detail="PriceSubscriptionService가 초기화되지 않았습니다")
26 category_key = f"ui_{req.reason}"
27 await svc.add_subscription(req.code, SubscriptionPriority.LOW, category_key)
28 return {"success": True, "code": req.code, "category": category_key}
31@router.post("/streaming/unsubscribe")
32async def unsubscribe_stock(req: SubscribeRequest):
33 """UI에서 특정 종목 실시간 가격 구독 해지."""
34 ctx = _get_ctx()
35 svc = getattr(ctx, "price_subscription_service", None)
36 if not svc:
37 raise HTTPException(status_code=503, detail="PriceSubscriptionService가 초기화되지 않았습니다")
39 category_key = f"ui_{req.reason}"
40 await svc.remove_subscription(req.code, category_key)
41 return {"success": True, "code": req.code, "category": category_key}
44@router.get("/streaming/status")
45def get_streaming_status():
46 """현재 실시간 구독 현황 반환."""
47 ctx = _get_ctx()
48 svc = getattr(ctx, "price_subscription_service", None)
49 if not svc:
50 return {"success": True, "data": {"active_count": 0, "active_codes": []}}
52 return {"success": True, "data": svc.get_status()}