first commit
This commit is contained in:
@@ -0,0 +1,267 @@
|
||||
"""
|
||||
Domain 注册中心
|
||||
|
||||
提供统一的 domain 组件注册和查询接口。
|
||||
各模块(Collection/DataSource/Strategy)按需获取。
|
||||
|
||||
使用方式:
|
||||
1. 在 domain/__init__.py 中注册所有组件
|
||||
2. 各模块按需查询
|
||||
|
||||
示例:
|
||||
# 注册
|
||||
from ..common.registry import DomainRegistry
|
||||
from .contract import ContractSyncNode, ContractJsonlHandler
|
||||
|
||||
DomainRegistry.register(
|
||||
node_type="contract",
|
||||
schema=ContractResponse,
|
||||
node_class=ContractSyncNode,
|
||||
jsonl_handler_class=ContractJsonlHandler
|
||||
)
|
||||
|
||||
# Collection 查询 SyncNode 类
|
||||
node_class = DomainRegistry.get_node_class("contract")
|
||||
|
||||
# DataSource 查询 Handler
|
||||
handler_class = DomainRegistry.get_jsonl_handler("contract")
|
||||
"""
|
||||
from typing import Dict, Type, Optional, Any
|
||||
from dataclasses import dataclass, field
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
@dataclass
|
||||
class DomainRegistration:
|
||||
"""
|
||||
单个 domain 的注册信息
|
||||
|
||||
包含:
|
||||
- node_class: SyncNode 子类(用于 Collection 恢复)
|
||||
- strategy_class: Strategy 子类(用于 SyncSystem 初始化)
|
||||
- handlers: 各种 Handler(用于 DataSource 初始化)
|
||||
"""
|
||||
node_type: str
|
||||
schema: Type[BaseModel]
|
||||
node_class: Type[Any] # Type[SyncNode[T]],避免循环导入
|
||||
strategy_class: Optional[Type[Any]] = None # 可选,部分 domain 可能只读
|
||||
jsonl_handler_class: Optional[Type[Any]] = None
|
||||
api_handler_class: Optional[Type[Any]] = None
|
||||
db_handler_class: Optional[Type[Any]] = None
|
||||
metadata: Dict[str, Any] = field(default_factory=dict) # 额外元数据
|
||||
|
||||
|
||||
class DomainRegistry:
|
||||
"""
|
||||
Domain 注册中心
|
||||
|
||||
职责分离:
|
||||
- Collection: 只关心 SyncNode 类(恢复类型)
|
||||
- DataSource: 只关心 Handler 类(执行层)
|
||||
- Strategy: 只关心 Strategy 类(业务逻辑)
|
||||
|
||||
每个 domain 只注册一次,各模块按需获取。
|
||||
"""
|
||||
|
||||
_registry: Dict[str, DomainRegistration] = {}
|
||||
|
||||
@classmethod
|
||||
def register(
|
||||
cls,
|
||||
node_type: str,
|
||||
schema: Type[BaseModel],
|
||||
node_class: Type[Any],
|
||||
strategy_class: Optional[Type[Any]] = None,
|
||||
jsonl_handler_class: Optional[Type[Any]] = None,
|
||||
api_handler_class: Optional[Type[Any]] = None,
|
||||
db_handler_class: Optional[Type[Any]] = None,
|
||||
**metadata
|
||||
) -> None:
|
||||
"""
|
||||
注册一个 domain
|
||||
|
||||
Args:
|
||||
node_type: 节点类型(如 "contract")
|
||||
schema: Pydantic Schema 类
|
||||
node_class: SyncNode 子类
|
||||
strategy_class: Strategy 子类(可选)
|
||||
jsonl_handler_class: JSONL Handler 类(可选)
|
||||
api_handler_class: API Handler 类(可选)
|
||||
db_handler_class: DB Handler 类(可选)
|
||||
**metadata: 额外的元数据
|
||||
|
||||
Raises:
|
||||
ValueError: 如果 node_type 已注册
|
||||
"""
|
||||
if node_type in cls._registry:
|
||||
raise ValueError(f"Domain '{node_type}' already registered")
|
||||
|
||||
cls._registry[node_type] = DomainRegistration(
|
||||
node_type=node_type,
|
||||
schema=schema,
|
||||
node_class=node_class,
|
||||
strategy_class=strategy_class,
|
||||
jsonl_handler_class=jsonl_handler_class,
|
||||
api_handler_class=api_handler_class,
|
||||
db_handler_class=db_handler_class,
|
||||
metadata=metadata
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_node_class(cls, node_type: str) -> Type[Any]:
|
||||
"""
|
||||
获取 SyncNode 类(用于 Collection 恢复)
|
||||
|
||||
Args:
|
||||
node_type: 节点类型
|
||||
|
||||
Returns:
|
||||
SyncNode 子类
|
||||
|
||||
Raises:
|
||||
ValueError: 如果 node_type 未注册
|
||||
"""
|
||||
reg = cls._registry.get(node_type)
|
||||
if not reg:
|
||||
raise ValueError(f"Unknown node_type: '{node_type}'. Available: {list(cls._registry.keys())}")
|
||||
return reg.node_class
|
||||
|
||||
@classmethod
|
||||
def get_strategy_class(cls, node_type: str) -> Optional[Type[Any]]:
|
||||
"""
|
||||
获取 Strategy 类(用于 SyncSystem)
|
||||
|
||||
Args:
|
||||
node_type: 节点类型
|
||||
|
||||
Returns:
|
||||
Strategy 类,如果未注册则返回 None
|
||||
"""
|
||||
reg = cls._registry.get(node_type)
|
||||
if not reg:
|
||||
raise ValueError(f"Unknown node_type: '{node_type}'")
|
||||
return reg.strategy_class
|
||||
|
||||
@classmethod
|
||||
def get_jsonl_handler(cls, node_type: str) -> Optional[Type[Any]]:
|
||||
"""
|
||||
获取 JSONL Handler 类(用于 DataSource)
|
||||
|
||||
Args:
|
||||
node_type: 节点类型
|
||||
|
||||
Returns:
|
||||
Handler 类,如果未注册则返回 None
|
||||
"""
|
||||
reg = cls._registry.get(node_type)
|
||||
if not reg:
|
||||
raise ValueError(f"Unknown node_type: '{node_type}'")
|
||||
return reg.jsonl_handler_class
|
||||
|
||||
@classmethod
|
||||
def get_api_handler(cls, node_type: str) -> Optional[Type[Any]]:
|
||||
"""获取 API Handler 类"""
|
||||
reg = cls._registry.get(node_type)
|
||||
if not reg:
|
||||
raise ValueError(f"Unknown node_type: '{node_type}'")
|
||||
return reg.api_handler_class
|
||||
|
||||
@classmethod
|
||||
def get_db_handler(cls, node_type: str) -> Optional[Type[Any]]:
|
||||
"""获取 DB Handler 类"""
|
||||
reg = cls._registry.get(node_type)
|
||||
if not reg:
|
||||
raise ValueError(f"Unknown node_type: '{node_type}'")
|
||||
return reg.db_handler_class
|
||||
|
||||
@classmethod
|
||||
def get_schema(cls, node_type: str) -> Type[BaseModel]:
|
||||
"""获取 Schema 类"""
|
||||
reg = cls._registry.get(node_type)
|
||||
if not reg:
|
||||
raise ValueError(f"Unknown node_type: '{node_type}'")
|
||||
return reg.schema
|
||||
|
||||
@classmethod
|
||||
def get_registration(cls, node_type: str) -> DomainRegistration:
|
||||
"""获取完整的注册信息"""
|
||||
reg = cls._registry.get(node_type)
|
||||
if not reg:
|
||||
raise ValueError(f"Unknown node_type: '{node_type}'")
|
||||
return reg
|
||||
|
||||
@classmethod
|
||||
def is_registered(cls, node_type: str) -> bool:
|
||||
"""检查 node_type 是否已注册"""
|
||||
return node_type in cls._registry
|
||||
|
||||
@classmethod
|
||||
def list_registered(cls) -> list[str]:
|
||||
"""列出所有已注册的 node_type"""
|
||||
return list(cls._registry.keys())
|
||||
|
||||
@classmethod
|
||||
def get_registered_types(cls) -> list[str]:
|
||||
"""列出所有已注册的 node_type(list_registered 的别名)"""
|
||||
return cls.list_registered()
|
||||
|
||||
@classmethod
|
||||
def clear(cls) -> None:
|
||||
"""清空注册表(仅用于测试)"""
|
||||
cls._registry.clear()
|
||||
|
||||
@classmethod
|
||||
def print_registry(cls) -> None:
|
||||
"""打印所有注册的 domain 信息(用于调试)"""
|
||||
if not cls._registry:
|
||||
print("⚠️ DomainRegistry is empty - no domains registered")
|
||||
return
|
||||
|
||||
print(f"\n{'='*80}")
|
||||
print(f"📋 DomainRegistry - {len(cls._registry)} domain(s) registered")
|
||||
print(f"{'='*80}\n")
|
||||
|
||||
for node_type, reg in sorted(cls._registry.items()):
|
||||
print(f"🔹 {node_type}")
|
||||
print(f" Schema: {reg.schema.__name__}")
|
||||
print(f" Node Class: {reg.node_class.__name__}")
|
||||
print(f" Strategy Class: {reg.strategy_class.__name__ if reg.strategy_class else '❌ None'}")
|
||||
print(f" JSONL Handler: {reg.jsonl_handler_class.__name__ if reg.jsonl_handler_class else '❌ None'}")
|
||||
print(f" API Handler: {reg.api_handler_class.__name__ if reg.api_handler_class else '❌ None'}")
|
||||
print(f" DB Handler: {reg.db_handler_class.__name__ if reg.db_handler_class else '❌ None'}")
|
||||
if reg.metadata:
|
||||
print(f" Metadata: {reg.metadata}")
|
||||
print()
|
||||
|
||||
print(f"{'='*80}\n")
|
||||
|
||||
@classmethod
|
||||
def get_summary(cls) -> Dict[str, Dict[str, bool]]:
|
||||
"""
|
||||
获取注册摘要(用于自动化检查)
|
||||
|
||||
Returns:
|
||||
字典,key 为 node_type,value 为各组件的注册状态
|
||||
|
||||
Example:
|
||||
{
|
||||
"contract": {
|
||||
"has_node": True,
|
||||
"has_strategy": True,
|
||||
"has_jsonl_handler": True,
|
||||
"has_api_handler": True,
|
||||
"has_db_handler": False
|
||||
},
|
||||
...
|
||||
}
|
||||
"""
|
||||
summary = {}
|
||||
for node_type, reg in cls._registry.items():
|
||||
summary[node_type] = {
|
||||
"has_node": reg.node_class is not None,
|
||||
"has_strategy": reg.strategy_class is not None,
|
||||
"has_jsonl_handler": reg.jsonl_handler_class is not None,
|
||||
"has_api_handler": reg.api_handler_class is not None,
|
||||
"has_db_handler": reg.db_handler_class is not None,
|
||||
}
|
||||
return summary
|
||||
Reference in New Issue
Block a user