Initial commit
This commit is contained in:
160
backend/test_api_safety.py
Executable file
160
backend/test_api_safety.py
Executable file
@@ -0,0 +1,160 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
API 모니터링 테스트 스크립트
|
||||
|
||||
KIS API의 재시도 및 쓰로틀링 기능을 테스트합니다.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# 프로젝트 루트 추가
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||||
|
||||
from app.services.korea_investment_api import KoreaInvestmentAPI
|
||||
import logging
|
||||
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def test_throttling():
|
||||
"""쓰로틀링 테스트: 빠른 연속 호출"""
|
||||
logger.info("=" * 60)
|
||||
logger.info("쓰로틀링 테스트 시작: 5개 종목 연속 조회")
|
||||
logger.info("=" * 60)
|
||||
|
||||
kis_api = KoreaInvestmentAPI()
|
||||
|
||||
test_stocks = [
|
||||
"005930", # 삼성전자
|
||||
"000660", # SK하이닉스
|
||||
"035420", # 네이버
|
||||
"051910", # LG화학
|
||||
"005380", # 현대차
|
||||
]
|
||||
|
||||
import time
|
||||
start = time.time()
|
||||
|
||||
for stock_code in test_stocks:
|
||||
logger.info(f"📊 Fetching {stock_code}...")
|
||||
try:
|
||||
result = await kis_api.get_current_price(stock_code)
|
||||
if result and result.get("output"):
|
||||
price = result["output"].get("stck_prpr", "N/A")
|
||||
logger.info(f"✅ {stock_code}: {price}원")
|
||||
except Exception as e:
|
||||
logger.error(f"❌ {stock_code}: {e}")
|
||||
|
||||
elapsed = time.time() - start
|
||||
logger.info(f"⏱️ Total time: {elapsed:.2f}초")
|
||||
logger.info(f"📈 Expected: ~{len(test_stocks) * kis_api.min_request_interval:.1f}초 (쓰로틀링 적용)")
|
||||
|
||||
# 통계 출력
|
||||
stats = kis_api.get_monitor_stats()
|
||||
logger.info("=" * 60)
|
||||
logger.info("📡 API 통계:")
|
||||
logger.info(f" - 총 호출: {stats['total_calls']}건")
|
||||
logger.info(f" - 오류: {stats['total_errors']}건")
|
||||
logger.info(f" - 재시도: {stats['total_retries']}건")
|
||||
logger.info(f" - 오류율: {stats['error_rate']:.1%}")
|
||||
logger.info(f" - 평균 응답: {stats['avg_duration']:.2f}초")
|
||||
logger.info("=" * 60)
|
||||
|
||||
|
||||
async def test_retry():
|
||||
"""재시도 테스트: 잘못된 종목 코드로 테스트"""
|
||||
logger.info("=" * 60)
|
||||
logger.info("재시도 테스트 시작: 오류 케이스")
|
||||
logger.info("=" * 60)
|
||||
|
||||
kis_api = KoreaInvestmentAPI()
|
||||
|
||||
# 잘못된 종목 코드
|
||||
invalid_code = "000000"
|
||||
|
||||
try:
|
||||
logger.info(f"📊 Fetching invalid stock: {invalid_code}")
|
||||
result = await kis_api.get_current_price(invalid_code)
|
||||
logger.info(f"✅ Result: {result}")
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Expected error: {e}")
|
||||
|
||||
# 통계 출력
|
||||
stats = kis_api.get_monitor_stats()
|
||||
logger.info("=" * 60)
|
||||
logger.info("📡 API 통계:")
|
||||
logger.info(f" - 총 호출: {stats['total_calls']}건")
|
||||
logger.info(f" - 오류: {stats['total_errors']}건")
|
||||
logger.info(f" - 재시도: {stats['total_retries']}건")
|
||||
logger.info(f" - 오류율: {stats['error_rate']:.1%}")
|
||||
logger.info("=" * 60)
|
||||
|
||||
|
||||
async def test_concurrent():
|
||||
"""동시 요청 테스트: 세마포어 확인"""
|
||||
logger.info("=" * 60)
|
||||
logger.info(f"동시 요청 테스트 시작 (최대 동시 요청: 2건)")
|
||||
logger.info("=" * 60)
|
||||
|
||||
kis_api = KoreaInvestmentAPI()
|
||||
|
||||
test_stocks = [
|
||||
"005930", # 삼성전자
|
||||
"000660", # SK하이닉스
|
||||
"035420", # 네이버
|
||||
"051910", # LG화학
|
||||
]
|
||||
|
||||
import time
|
||||
start = time.time()
|
||||
|
||||
# 병렬 실행
|
||||
tasks = [kis_api.get_current_price(code) for code in test_stocks]
|
||||
results = await asyncio.gather(*tasks, return_exceptions=True)
|
||||
|
||||
elapsed = time.time() - start
|
||||
|
||||
success = sum(1 for r in results if not isinstance(r, Exception))
|
||||
logger.info(f"✅ 성공: {success}/{len(test_stocks)}")
|
||||
logger.info(f"⏱️ Total time: {elapsed:.2f}초")
|
||||
|
||||
# 통계 출력
|
||||
stats = kis_api.get_monitor_stats()
|
||||
logger.info("=" * 60)
|
||||
logger.info("📡 API 통계:")
|
||||
logger.info(f" - 총 호출: {stats['total_calls']}건")
|
||||
logger.info(f" - 오류: {stats['total_errors']}건")
|
||||
logger.info(f" - 재시도: {stats['total_retries']}건")
|
||||
logger.info(f" - 오류율: {stats['error_rate']:.1%}")
|
||||
logger.info(f" - 평균 응답: {stats['avg_duration']:.2f}초")
|
||||
logger.info("=" * 60)
|
||||
|
||||
|
||||
async def main():
|
||||
"""메인 테스트 실행"""
|
||||
logger.info("🚀 KIS API 안전 운영 테스트 시작")
|
||||
logger.info("")
|
||||
|
||||
# 1. 쓰로틀링 테스트
|
||||
await test_throttling()
|
||||
await asyncio.sleep(2)
|
||||
|
||||
# 2. 재시도 테스트
|
||||
await test_retry()
|
||||
await asyncio.sleep(2)
|
||||
|
||||
# 3. 동시 요청 테스트
|
||||
await test_concurrent()
|
||||
|
||||
logger.info("")
|
||||
logger.info("✅ 모든 테스트 완료")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
Reference in New Issue
Block a user