Build lightweight AI agent admin
This commit is contained in:
@@ -0,0 +1,205 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
资源类型注册表 - 自动注册和管理所有资源类型
|
||||
"""
|
||||
import re
|
||||
from typing import Dict, List, Type, Optional
|
||||
|
||||
|
||||
class ResourceRegistry:
|
||||
"""
|
||||
资源类型注册表
|
||||
|
||||
自动注册所有定义了 RESOURCE_TYPE 的 Service,
|
||||
并提供查询、验证等功能
|
||||
"""
|
||||
|
||||
# 存储所有已注册的资源类型
|
||||
# 格式: {resource_type: {"service": ServiceClass, "model": ModelClass, "name": "显示名称"}}
|
||||
_registry: Dict[str, Dict] = {}
|
||||
|
||||
@classmethod
|
||||
def register(
|
||||
cls,
|
||||
resource_type: str,
|
||||
service_class: Type,
|
||||
display_name: Optional[str] = None,
|
||||
application_id: Optional[str] = None,
|
||||
field_metadata: Optional[Dict[str, Dict]] = None
|
||||
):
|
||||
"""
|
||||
注册资源类型
|
||||
|
||||
:param resource_type: 资源类型标识(如 'customer', 'order')
|
||||
:param service_class: Service 类
|
||||
:param display_name: 显示名称(可选,如 '客户', '订单')
|
||||
:param application_id: 应用ID(可选,用于子应用过滤)
|
||||
:param field_metadata: 字段元数据(可选,用于字段权限配置)
|
||||
"""
|
||||
if resource_type in cls._registry:
|
||||
# 如果已存在,更新信息
|
||||
cls._registry[resource_type].update({
|
||||
'service': service_class,
|
||||
'display_name': display_name or cls._registry[resource_type].get('display_name', resource_type),
|
||||
'application_id': application_id or cls._registry[resource_type].get('application_id'),
|
||||
'field_metadata': field_metadata or cls._registry[resource_type].get('field_metadata')
|
||||
})
|
||||
else:
|
||||
# 新注册
|
||||
cls._registry[resource_type] = {
|
||||
'service': service_class,
|
||||
'model': service_class.model if service_class and hasattr(service_class, 'model') else None,
|
||||
'display_name': display_name or cls._generate_display_name(resource_type),
|
||||
'application_id': application_id,
|
||||
'field_metadata': field_metadata
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def _generate_display_name(cls, resource_type: str) -> str:
|
||||
"""
|
||||
根据资源类型生成显示名称
|
||||
|
||||
:param resource_type: 资源类型(如 'customer_order')
|
||||
:return: 显示名称(如 '客户订单')
|
||||
"""
|
||||
# 将下划线分隔的单词转换为空格分隔,并首字母大写
|
||||
words = resource_type.split('_')
|
||||
return ' '.join(word.capitalize() for word in words)
|
||||
|
||||
@classmethod
|
||||
def get_all_resource_types(cls) -> List[str]:
|
||||
"""
|
||||
获取所有已注册的资源类型
|
||||
|
||||
:return: 资源类型列表
|
||||
"""
|
||||
return list(cls._registry.keys())
|
||||
|
||||
@classmethod
|
||||
def get_all_resources(cls, application_id: Optional[str] = None) -> List[Dict]:
|
||||
"""
|
||||
获取所有已注册的资源信息
|
||||
|
||||
:param application_id: 应用ID,如果指定则只返回该应用的资源(严格匹配)
|
||||
:return: 资源信息列表,每个元素包含 resource_type, display_name, model_name 等
|
||||
"""
|
||||
resources = []
|
||||
for resource_type, info in cls._registry.items():
|
||||
# 如果指定了应用ID,只返回该应用的资源(严格匹配,不显示无应用ID的资源)
|
||||
if application_id:
|
||||
resource_app_id = info.get('application_id')
|
||||
# 只显示匹配该应用ID的资源
|
||||
if resource_app_id != application_id:
|
||||
continue
|
||||
|
||||
resources.append({
|
||||
'resource_type': resource_type,
|
||||
'display_name': info.get('display_name', resource_type),
|
||||
'model_name': info['model'].__name__ if info.get('model') else None,
|
||||
'table_name': info['model'].__tablename__ if info.get('model') and hasattr(info['model'], '__tablename__') else None,
|
||||
'application_id': info.get('application_id')
|
||||
})
|
||||
return resources
|
||||
|
||||
@classmethod
|
||||
def get_resource(cls, resource_type: str) -> Optional[Dict]:
|
||||
"""
|
||||
根据资源类型获取完整的资源信息
|
||||
|
||||
:param resource_type: 资源类型
|
||||
:return: 资源信息字典或 None
|
||||
"""
|
||||
return cls._registry.get(resource_type)
|
||||
|
||||
@classmethod
|
||||
def get_service(cls, resource_type: str) -> Optional[Type]:
|
||||
"""
|
||||
根据资源类型获取对应的 Service 类
|
||||
|
||||
:param resource_type: 资源类型
|
||||
:return: Service 类或 None
|
||||
"""
|
||||
info = cls._registry.get(resource_type)
|
||||
return info.get('service') if info else None
|
||||
|
||||
@classmethod
|
||||
def validate_resource_type(cls, resource_type: str) -> bool:
|
||||
"""
|
||||
验证资源类型是否已注册(别名方法)
|
||||
|
||||
:param resource_type: 资源类型
|
||||
:return: True 表示已注册,False 表示未注册
|
||||
"""
|
||||
return resource_type in cls._registry
|
||||
|
||||
@classmethod
|
||||
def validate(cls, resource_type: str) -> bool:
|
||||
"""
|
||||
验证资源类型是否已注册
|
||||
|
||||
:param resource_type: 资源类型
|
||||
:return: True 表示已注册,False 表示未注册
|
||||
"""
|
||||
return resource_type in cls._registry
|
||||
|
||||
@classmethod
|
||||
def unregister(cls, resource_type: str) -> bool:
|
||||
"""
|
||||
注销资源类型
|
||||
|
||||
:param resource_type: 资源类型标识
|
||||
:return: True 表示成功注销,False 表示资源类型不存在
|
||||
"""
|
||||
if resource_type in cls._registry:
|
||||
del cls._registry[resource_type]
|
||||
return True
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def clear(cls):
|
||||
"""清空注册表(主要用于测试)"""
|
||||
cls._registry.clear()
|
||||
|
||||
@classmethod
|
||||
def get_registry_info(cls) -> Dict:
|
||||
"""
|
||||
获取注册表的统计信息
|
||||
|
||||
:return: 统计信息字典
|
||||
"""
|
||||
return {
|
||||
'total_count': len(cls._registry),
|
||||
'resource_types': cls.get_all_resource_types(),
|
||||
'resources': cls.get_all_resources()
|
||||
}
|
||||
|
||||
|
||||
def auto_generate_resource_type(model_class: Type) -> str:
|
||||
"""
|
||||
根据模型类自动生成资源类型
|
||||
|
||||
规则:
|
||||
1. 优先使用表名(去除前缀如 core_, sys_)
|
||||
2. 如果没有表名,使用模型名(驼峰转下划线)
|
||||
|
||||
:param model_class: 模型类
|
||||
:return: 资源类型字符串
|
||||
"""
|
||||
# 尝试从表名生成
|
||||
if hasattr(model_class, '__tablename__'):
|
||||
table_name = model_class.__tablename__
|
||||
|
||||
# 移除常见前缀
|
||||
for prefix in ['core_', 'sys_', 'app_', 'biz_']:
|
||||
if table_name.startswith(prefix):
|
||||
return table_name[len(prefix):]
|
||||
|
||||
return table_name
|
||||
|
||||
# 从模型名生成(驼峰转下划线)
|
||||
model_name = model_class.__name__
|
||||
# Customer → customer, CustomerOrder → customer_order
|
||||
resource_type = re.sub(r'(?<!^)(?=[A-Z])', '_', model_name).lower()
|
||||
|
||||
return resource_type
|
||||
Reference in New Issue
Block a user