From cd462890ffdebe74bdb889ca519c251bad67efef Mon Sep 17 00:00:00 2001 From: Heewon Oh Date: Wed, 3 Jun 2026 21:35:21 +0900 Subject: [PATCH] feat(constants): add get_ws_url helper for real/mock WebSocket selection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v1.7.0에서 도입했지만 미사용으로 dead code 상태였던 WS_MOCK_URL을 활성화. KIS 공식 샘플 코드(open-trading-api/legacy/websocket/python/*)에서 모의투자 WS 엔드포인트가 ws://ops.koreainvestment.com:31000임을 확인. 추가: - kis_agent.core.constants.get_ws_url(is_real: bool = True) -> str 실전/모의 분기 헬퍼. 기본은 실전(기존 동작 호환). - kis_agent/websocket/__init__.py 도크스트링에 모의 엔드포인트 사용 예제 추가. 기존 WSAgent/KisWebSocket 시그니처는 변경하지 않음(url 매개변수에 직접 전달). 사용자가 명시적으로 get_ws_url(False)로 선택할 수 있게 된 점이 가장 큰 차이. --- kis_agent/core/constants.py | 24 ++++++++++++++++++++++++ kis_agent/websocket/__init__.py | 4 ++++ 2 files changed, 28 insertions(+) diff --git a/kis_agent/core/constants.py b/kis_agent/core/constants.py index e43207b..9f921c6 100644 --- a/kis_agent/core/constants.py +++ b/kis_agent/core/constants.py @@ -11,12 +11,35 @@ REAL_BASE_URL = "https://openapi.koreainvestment.com:9443" MOCK_BASE_URL = "https://openapivts.koreainvestment.com:29443" +# WebSocket 엔드포인트 +# (KIS 공식 샘플 open-trading-api/legacy/websocket/python/* 에서 확인된 값) WS_REAL_URL = "ws://ops.koreainvestment.com:21000" WS_MOCK_URL = "ws://ops.koreainvestment.com:31000" KIS_USER_AGENT_DEFAULT = "KIS_AGENT" +def get_ws_url(is_real: bool = True) -> str: + """실전/모의 WebSocket URL을 선택한다. + + KIS는 실전과 모의 WS 엔드포인트를 분리 운영한다: + - 실전: `ws://ops.koreainvestment.com:21000` (`WS_REAL_URL`) + - 모의: `ws://ops.koreainvestment.com:31000` (`WS_MOCK_URL`) + + Args: + is_real: True면 실전 URL, False면 모의 URL. + + Returns: + 선택된 WebSocket URL. + + Example: + >>> from kis_agent.core.constants import get_ws_url + >>> from kis_agent.websocket import WSAgent + >>> ws = WSAgent(approval_key, url=get_ws_url(is_real=False)) + """ + return WS_REAL_URL if is_real else WS_MOCK_URL + + class AccountProductCode(str, Enum): """계좌 상품코드 (KIS 공식). @@ -35,4 +58,5 @@ class AccountProductCode(str, Enum): "WS_MOCK_URL", "KIS_USER_AGENT_DEFAULT", "AccountProductCode", + "get_ws_url", ] diff --git a/kis_agent/websocket/__init__.py b/kis_agent/websocket/__init__.py index ff3a334..c5f0d23 100644 --- a/kis_agent/websocket/__init__.py +++ b/kis_agent/websocket/__init__.py @@ -17,6 +17,10 @@ ws.subscribe_stocks(["005930", "000660"]) await ws.connect() + # 모의투자 엔드포인트 사용 + from kis_agent.core.constants import get_ws_url + ws = WSAgent(approval_key, url=get_ws_url(is_real=False)) + .. deprecated:: 1.3.0 KisWebSocket, EnhancedWebSocketClient, RefactoredWebSocketClient, WebSocketClientFactory, WebSocketClientBuilder는 deprecated되었습니다.