Coverage for aipyapp/interface.py: 53%
75 statements
« prev ^ index » next coverage.py v7.10.3, created at 2025-08-11 13:03 +0200
« prev ^ index » next coverage.py v7.10.3, created at 2025-08-11 13:03 +0200
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
4import threading
5from abc import ABC, abstractmethod
6from typing import Callable, Any, Dict, List, Optional, Protocol
8from loguru import logger
10class Trackable(ABC):
11 """可追踪对象接口"""
13 @abstractmethod
14 def get_checkpoint(self) -> Any:
15 """获取当前检查点状态"""
16 pass
18 @abstractmethod
19 def restore_to_checkpoint(self, checkpoint: Optional[Any]):
20 """恢复到指定检查点,None表示恢复到初始状态"""
21 pass
23class Runtime(ABC):
24 @abstractmethod
25 def install_packages(self, packages):
26 pass
28 @abstractmethod
29 def getenv(self, name, desc=None):
30 pass
32class ConsoleInterface(ABC):
33 @abstractmethod
34 def print(self, *args, sep=' ', end='\n', file=None, flush=False):
35 pass
37 @abstractmethod
38 def input(self, prompt=''):
39 pass
41 @abstractmethod
42 def status(self, msg):
43 pass
45class Stoppable():
46 def __init__(self):
47 super().__init__()
48 self._stop_event = threading.Event()
50 def on_stop(self):
51 pass
53 def stop(self):
54 self._stop_event.set()
55 self.on_stop()
57 def is_stopped(self):
58 return self._stop_event.is_set()
60 def wait(self, timeout=None):
61 return self._stop_event.wait(timeout)
63 def reset(self):
64 self._stop_event.clear()
66class Event:
67 def __init__(self, name: str, **data):
68 self.name = name
69 self.data = data
71 def __str__(self):
72 return f"{self.name}: {self.data}"
74 def __getattr__(self, name: str):
75 return self.data.get(name)
77EventHandler = Callable[[Event], None]
79class EventListener(Protocol):
80 def get_handlers(self) -> Dict[str, EventHandler]:
81 ...
83class EventBus:
84 def __init__(self):
85 super().__init__()
86 self._listeners: Dict[str, List[EventHandler]] = {}
87 self._eb_logger = logger.bind(src=self.__class__.__name__)
89 def on_event(self, event_name: str, handler: EventHandler):
90 self._listeners.setdefault(event_name, []).append(handler)
92 def add_listener(self, obj: EventListener):
93 count = 0
94 for event_name, handler in obj.get_handlers().items():
95 self.on_event(event_name, handler)
96 count += 1
97 self._eb_logger.info(f"Registered {count} events for {obj.__class__.__name__}")
99 def emit(self, event_name: str, **kwargs):
100 event = Event(event_name, **kwargs)
101 for handler in self._listeners.get(event_name, []):
102 try:
103 handler(event)
104 except Exception as e:
105 self._eb_logger.exception(f"Error emitting event {event_name}")
106 return event
109__all__ = ['Trackable', 'Runtime', 'Stoppable', 'Event', 'EventHandler', 'EventListener', 'EventBus']