feat(kis): cache tokens in sqlite and add inspector

This commit is contained in:
2026-06-23 18:00:34 +09:00
parent a343db5812
commit 357d2507da
3 changed files with 207 additions and 27 deletions
+98
View File
@@ -4,6 +4,9 @@ import sys
import unittest
from pathlib import Path
from unittest.mock import patch
import warnings
warnings.simplefilter("ignore", ResourceWarning)
ROOT = Path(__file__).resolve().parents[2]
if str(ROOT) not in sys.path:
@@ -154,6 +157,101 @@ class TestKisApiClientV1(unittest.TestCase):
shutil.rmtree(tmp_dir, ignore_errors=True)
def test_issue_or_reuse_token_honors_token_db_override(self):
import tempfile
import shutil
import sqlite3
from src.quant_engine.kis_api_client_v1 import _issue_or_reuse_token, KisCredentials
tmp_dir = tempfile.mkdtemp()
override_db = Path(tmp_dir) / "custom_kis_tokens.db"
with patch.dict("os.environ", {"KIS_TOKEN_DB_PATH": str(override_db)}), \
patch("src.quant_engine.kis_api_client_v1._requests") as mock_requests:
creds = KisCredentials(app_key="k", app_secret="s", account="mock")
mock_resp = mock_requests.return_value.post.return_value
mock_resp.raise_for_status.return_value = None
mock_resp.json.return_value = {
"access_token": "override-token-789",
"expires_in": "3600",
}
token = _issue_or_reuse_token(creds)
self.assertEqual(token, "override-token-789")
self.assertTrue(override_db.exists())
with sqlite3.connect(override_db) as conn:
row = conn.execute(
"SELECT access_token FROM kis_tokens WHERE account = 'mock'"
).fetchone()
self.assertIsNotNone(row)
self.assertEqual(row[0], "override-token-789")
shutil.rmtree(tmp_dir, ignore_errors=True)
def test_issue_or_reuse_token_serializes_concurrent_refresh(self):
import tempfile
import shutil
import sqlite3
import threading
import time
from src.quant_engine.kis_api_client_v1 import _issue_or_reuse_token, KisCredentials
tmp_dir = tempfile.mkdtemp()
override_db = Path(tmp_dir) / "kis_tokens.db"
barrier = threading.Barrier(2)
post_calls = []
class _Response:
def raise_for_status(self):
return None
def json(self):
return {
"access_token": "concurrent-token-001",
"expires_in": "3600",
}
def _post(*args, **kwargs):
post_calls.append(time.time())
time.sleep(0.2)
return _Response()
with patch.dict("os.environ", {"KIS_TOKEN_DB_PATH": str(override_db)}), \
patch("src.quant_engine.kis_api_client_v1._requests") as mock_requests:
mock_requests.return_value.post.side_effect = _post
creds = KisCredentials(app_key="k", app_secret="s", account="mock")
results: list[str] = []
errors: list[BaseException] = []
def worker() -> None:
try:
barrier.wait(timeout=5)
results.append(_issue_or_reuse_token(creds))
except BaseException as exc: # pragma: no cover - test harness diagnostic
errors.append(exc)
t1 = threading.Thread(target=worker)
t2 = threading.Thread(target=worker)
t1.start()
t2.start()
t1.join(timeout=10)
t2.join(timeout=10)
self.assertEqual(errors, [])
self.assertEqual(results, ["concurrent-token-001", "concurrent-token-001"])
self.assertEqual(len(post_calls), 1)
with sqlite3.connect(override_db) as conn:
row = conn.execute(
"SELECT access_token FROM kis_tokens WHERE account = 'mock'"
).fetchone()
self.assertIsNotNone(row)
self.assertEqual(row[0], "concurrent-token-001")
shutil.rmtree(tmp_dir, ignore_errors=True)
if __name__ == "__main__":
unittest.main()