Files
njts-accounting-core/backend/app/modules/egov/state.py
2026-05-20 17:45:09 +09:00

86 lines
3.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import asyncio
import time
from enum import Enum
from typing import Optional, Any
class EGovStatus(str, Enum):
IDLE = "idle"
STARTING = "starting"
WAITING_MFA = "waiting_mfa"
LOGGED_IN = "logged_in"
DOWNLOADING = "downloading"
ERROR = "error"
class EGovState:
def __init__(self):
self.status: EGovStatus = EGovStatus.IDLE
self.message: str = ""
self.mfa_event: asyncio.Event = asyncio.Event()
self.mfa_code: Optional[str] = None
self.screenshot_b64: Optional[str] = None
self.last_download: Optional[dict] = None # {filename, path, size}
# ブラウザセッションPlaywright 方式, 後方互換用)
self._playwright: Optional[Any] = None
self._browser: Optional[Any] = None
self._context: Optional[Any] = None
self._page: Optional[Any] = None
# ── OAuth2 / e-Gov API 方式 ──────────────────────────────
self.access_token: Optional[str] = None
self.refresh_token: Optional[str] = None
self.token_expires_at: Optional[float] = None # unix timestamp
self._pkce_verifier: Optional[str] = None
self._oauth_state: Optional[str] = None
def is_token_valid(self) -> bool:
"""アクセストークンが有効かどうかを返す60秒マージン"""
if not self.access_token:
return False
if self.token_expires_at and time.time() >= self.token_expires_at - 60:
return False
return True
def set_tokens(self, token_response: dict):
"""トークンレスポンスをステートにセット"""
self.access_token = token_response.get("access_token")
self.refresh_token = token_response.get("refresh_token")
expires_in = token_response.get("expires_in", 300)
self.token_expires_at = time.time() + int(expires_in)
def reset(self):
self.status = EGovStatus.IDLE
self.message = ""
self.mfa_event = asyncio.Event()
self.mfa_code = None
self.screenshot_b64 = None
self.last_download = None
self.access_token = None
self.refresh_token = None
self.token_expires_at = None
self._pkce_verifier = None
self._oauth_state = None
async def close_browser(self):
"""ブラウザを閉じてリソースを解放"""
try:
if self._browser:
await self._browser.close()
except Exception:
pass
try:
if self._playwright:
await self._playwright.stop()
except Exception:
pass
self._playwright = None
self._browser = None
self._context = None
self._page = None
# モジュールレベルのシングルトン
state = EGovState()