hpce-dev / core /extractor.py
์ด๋™ํ˜„
[DOCS] ๋ฐฑ์—”๋“œ ์ „๋ฐ˜ docstring ๋ณด๊ฐ• (Google ์Šคํƒ€์ผ Args/Returns/Raises)
58debbc
Raw
History Blame Contribute Delete
3.55 kB
from __future__ import annotations
"""
Behavioral ์ด๋ฒคํŠธ ๊ณต์œ  ์ €์žฅ์†Œ (์‹œ๋‚˜๋ฆฌ์˜ค ๋ฌด๊ด€).
์„ธ์…˜๋ณ„ ํ–‰๋™ ์ด๋ฒคํŠธ๋ฅผ ๋ˆ„์ ํ•˜๊ณ  5๋ถ„ window๋กœ ์กฐํšŒํ•œ๋‹ค.
Pattern Feature ์‚ฐ์ถœ(์‹œ๋‚˜๋ฆฌ์˜ค๋ณ„ ์ง‘๊ณ„)์€ ๊ฐ ์—”์ง„(cs/bundle/worker)์ด ๋‹ด๋‹น.
"""
from datetime import datetime, timedelta
from typing import Any
def _now() -> datetime:
"""ํ˜„์žฌ UTC ์‹œ๊ฐ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค (์ด๋ฒคํŠธ ํƒ€์ž„์Šคํƒฌํ”„ยทwindow ์ปท์˜คํ”„ ๊ธฐ์ค€).
Returns:
ํ˜„์žฌ UTC datetime.
"""
return datetime.utcnow()
class BehavioralPatternExtractor:
"""์„ธ์…˜๋ณ„ ํ–‰๋™ ์ด๋ฒคํŠธ๋ฅผ ๋ˆ„์ ํ•˜๊ณ  window ๋‹จ์œ„๋กœ ์กฐํšŒํ•œ๋‹ค.
WebSocket ์„ธ์…˜ ๋‹จ์œ„๋กœ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ณด์กดํ•˜๋ฉฐ, ๋งค ํ–‰๋™๋งˆ๋‹ค add_event()๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.
Pattern Feature ์‚ฐ์ถœ์€ ๊ฐ ์‹œ๋‚˜๋ฆฌ์˜ค ์—”์ง„์ด ๋‹ด๋‹นํ•œ๋‹ค.
"""
def __init__(self) -> None:
self._events_by_session: dict[str, list[dict[str, Any]]] = {}
def add_event(
self,
session_id: str,
event_type: str,
entity: str,
occurred_at: datetime | None = None,
) -> None:
"""์„ธ์…˜์— ํ–‰๋™ ์ด๋ฒคํŠธ 1๊ฑด์„ ๋ˆ„์ ํ•œ๋‹ค.
Args:
session_id: ์ด๋ฒคํŠธ๋ฅผ ๋ˆ„์ ํ•  ์„ธ์…˜ ID.
event_type: ์ด๋ฒคํŠธ ์ข…๋ฅ˜.
entity: ์ด๋ฒคํŠธ ๋Œ€์ƒ ์—”ํ‹ฐํ‹ฐ.
occurred_at: ์ด๋ฒคํŠธ ๋ฐœ์ƒ ์‹œ๊ฐ. ๋ฏธ์ง€์ • ์‹œ ํ˜„์žฌ UTC.
"""
ts = occurred_at or _now()
self._events_by_session.setdefault(session_id, []).append({
"event_type": event_type,
"entity": entity,
"occurred_at": ts,
})
def events_within(
self,
session_id: str,
window_seconds: int = 300,
) -> list[dict[str, Any]]:
"""์„ธ์…˜์˜ ์ตœ๊ทผ window ๋‚ด ์ด๋ฒคํŠธ๋ฅผ ์กฐํšŒํ•œ๋‹ค.
์—”์ง„๋ณ„ Pattern ๊ณ„์‚ฐ ์ž…๋ ฅ์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.
Args:
session_id: ์กฐํšŒํ•  ์„ธ์…˜ ID.
window_seconds: ์ปท์˜คํ”„ window ๊ธธ์ด(์ดˆ).
Returns:
์ปท์˜คํ”„ ์ดํ›„ ๋ฐœ์ƒํ•œ ์ด๋ฒคํŠธ ๋ฆฌ์ŠคํŠธ.
"""
events = self._events_by_session.get(session_id, [])
cutoff = _now() - timedelta(seconds=window_seconds)
return [e for e in events if e["occurred_at"] >= cutoff]
def recent_events(self, session_id: str, n: int) -> list[dict[str, Any]]:
"""์„ธ์…˜์˜ ์ตœ๊ทผ n๊ฐœ ์ด๋ฒคํŠธ๋ฅผ ์กฐํšŒํ•œ๋‹ค (ํด๋ฆญ ๊ธฐ๋ฐ˜ ์œˆ๋„์šฐ).
Args:
session_id: ์กฐํšŒํ•  ์„ธ์…˜ ID.
n: ์กฐํšŒํ•  ์ตœ๊ทผ ์ด๋ฒคํŠธ ๊ฐœ์ˆ˜. 0 ์ดํ•˜์ด๋ฉด ์ „์ฒด.
Returns:
์ตœ๊ทผ n๊ฐœ ์ด๋ฒคํŠธ ๋ฆฌ์ŠคํŠธ.
"""
events = self._events_by_session.get(session_id, [])
return events[-n:] if n and n > 0 else list(events)
def reset(self, session_id: str) -> None:
"""์„ธ์…˜์˜ ๋ˆ„์  ์ด๋ฒคํŠธ๋ฅผ ์ œ๊ฑฐํ•œ๋‹ค.
Args:
session_id: ์ดˆ๊ธฐํ™”ํ•  ์„ธ์…˜ ID.
"""
self._events_by_session.pop(session_id, None)
# โ”€โ”€ ์‹ฑ๊ธ€ํ†ค ์ธ์Šคํ„ด์Šค โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
_extractor: BehavioralPatternExtractor | None = None
def get_extractor() -> BehavioralPatternExtractor:
"""๊ณต์œ  ์ด๋ฒคํŠธ ์ €์žฅ์†Œ ์‹ฑ๊ธ€ํ†ค์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
Returns:
ํ”„๋กœ์„ธ์Šค ์ „์—ญ BehavioralPatternExtractor ์ธ์Šคํ„ด์Šค.
"""
global _extractor
if _extractor is None:
_extractor = BehavioralPatternExtractor()
return _extractor