⚡ 初始提交 - FutureOSS v1.0 插件化运行时框架
一切皆为插件的开发者工具运行时框架
🧩 核心特性:
- 插件热插拔 (importlib 动态加载)
- 依赖自动解析 (拓扑排序 + 循环检测)
- 企业级稳定 (熔断/降级/重试/隔离)
- 事件驱动 (发布/订阅事件总线)
- 完整配置 (YAML 配置 + 热重载)
This commit is contained in:
83
store/@{FutureOSS}/json-codec/README.md
Normal file
83
store/@{FutureOSS}/json-codec/README.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# json-codec JSON 编解码器
|
||||
|
||||
提供插件间 JSON 数据的编码、解码和验证功能。
|
||||
|
||||
## 功能
|
||||
|
||||
- **JSON 编码**: Python 对象 → JSON 字符串
|
||||
- **JSON 解码**: JSON 字符串 → Python 对象
|
||||
- **Schema 验证**: 验证 JSON 数据结构
|
||||
- **自定义类型**: 支持注册自定义类型编解码器
|
||||
|
||||
## 基本使用
|
||||
|
||||
```python
|
||||
codec = plugin_mgr.get("json-codec")
|
||||
|
||||
# 编码
|
||||
data = {"name": "test", "count": 42}
|
||||
json_str = codec.encode(data)
|
||||
# '{"name": "test", "count": 42}'
|
||||
|
||||
# 编码(格式化)
|
||||
json_pretty = codec.encode(data, pretty=True)
|
||||
# '{\n "name": "test",\n "count": 42\n}'
|
||||
|
||||
# 解码
|
||||
parsed = codec.decode(json_str)
|
||||
# {"name": "test", "count": 42}
|
||||
```
|
||||
|
||||
## HTTP 响应处理
|
||||
|
||||
```python
|
||||
# 在 http-api 插件中使用
|
||||
router.get("/api/users", lambda req: Response(
|
||||
status=200,
|
||||
headers={"Content-Type": "application/json"},
|
||||
body=codec.encode({"users": [...]})
|
||||
))
|
||||
```
|
||||
|
||||
## Schema 验证
|
||||
|
||||
```python
|
||||
# 注册 schema
|
||||
codec.register_schema("user", {
|
||||
"type": "object",
|
||||
"required": ["name", "email"],
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"email": {"type": "string"},
|
||||
"age": {"type": "number"}
|
||||
}
|
||||
})
|
||||
|
||||
# 验证数据
|
||||
user_data = {"name": "test", "email": "test@example.com"}
|
||||
is_valid = codec.validate(user_data, "user")
|
||||
```
|
||||
|
||||
## 自定义类型
|
||||
|
||||
```python
|
||||
from datetime import datetime
|
||||
|
||||
# 注册自定义编码器
|
||||
codec.serializer.register_encoder(datetime, lambda dt: dt.isoformat())
|
||||
|
||||
# 使用
|
||||
data = {"created_at": datetime.now()}
|
||||
json_str = codec.encode(data)
|
||||
```
|
||||
|
||||
## 错误处理
|
||||
|
||||
```python
|
||||
from oss.plugin.types import JsonCodecError
|
||||
|
||||
try:
|
||||
result = codec.decode("invalid json")
|
||||
except JsonCodecError as e:
|
||||
print(f"解码失败: {e}")
|
||||
```
|
||||
BIN
store/@{FutureOSS}/json-codec/__pycache__/main.cpython-313.pyc
Normal file
BIN
store/@{FutureOSS}/json-codec/__pycache__/main.cpython-313.pyc
Normal file
Binary file not shown.
161
store/@{FutureOSS}/json-codec/main.py
Normal file
161
store/@{FutureOSS}/json-codec/main.py
Normal file
@@ -0,0 +1,161 @@
|
||||
"""JSON 编解码器 - 插件间 JSON 数据处理"""
|
||||
import json
|
||||
from typing import Any, Callable, Optional
|
||||
from datetime import datetime
|
||||
|
||||
from oss.plugin.types import Plugin, register_plugin_type
|
||||
|
||||
|
||||
class JsonCodecError(Exception):
|
||||
"""JSON 编解码错误"""
|
||||
pass
|
||||
|
||||
|
||||
class JsonSerializer:
|
||||
"""JSON 序列化器"""
|
||||
|
||||
def __init__(self):
|
||||
self._custom_encoders: dict[type, Callable] = {}
|
||||
|
||||
def register_encoder(self, type_class: type, encoder: Callable):
|
||||
"""注册自定义类型编码器"""
|
||||
self._custom_encoders[type_class] = encoder
|
||||
|
||||
def encode(self, data: Any, pretty: bool = False) -> str:
|
||||
"""编码为 JSON 字符串"""
|
||||
def default_handler(obj):
|
||||
if isinstance(obj, datetime):
|
||||
return obj.isoformat()
|
||||
for type_class, encoder in self._custom_encoders.items():
|
||||
if isinstance(obj, type_class):
|
||||
return encoder(obj)
|
||||
raise TypeError(f"无法序列化类型: {type(obj).__name__}")
|
||||
|
||||
if pretty:
|
||||
return json.dumps(data, ensure_ascii=False, indent=2, default=default_handler)
|
||||
return json.dumps(data, ensure_ascii=False, default=default_handler)
|
||||
|
||||
def encode_to_bytes(self, data: Any) -> bytes:
|
||||
"""编码为字节"""
|
||||
return self.encode(data).encode("utf-8")
|
||||
|
||||
|
||||
class JsonDeserializer:
|
||||
"""JSON 反序列化器"""
|
||||
|
||||
def __init__(self):
|
||||
self._custom_decoders: dict[str, Callable] = {}
|
||||
|
||||
def register_decoder(self, type_name: str, decoder: Callable):
|
||||
"""注册自定义类型解码器"""
|
||||
self._custom_decoders[type_name] = decoder
|
||||
|
||||
def decode(self, text: str) -> Any:
|
||||
"""解码 JSON 字符串"""
|
||||
try:
|
||||
return json.loads(text)
|
||||
except json.JSONDecodeError as e:
|
||||
raise JsonCodecError(f"JSON 解码失败: {e}")
|
||||
|
||||
def decode_bytes(self, data: bytes) -> Any:
|
||||
"""解码字节"""
|
||||
return self.decode(data.decode("utf-8"))
|
||||
|
||||
def decode_file(self, path: str) -> Any:
|
||||
"""解码 JSON 文件"""
|
||||
with open(path, "r", encoding="utf-8") as f:
|
||||
return self.decode(f.read())
|
||||
|
||||
|
||||
class JsonValidator:
|
||||
"""JSON 验证器"""
|
||||
|
||||
def __init__(self):
|
||||
self._schemas: dict[str, dict] = {}
|
||||
|
||||
def register_schema(self, name: str, schema: dict):
|
||||
"""注册 schema"""
|
||||
self._schemas[name] = schema
|
||||
|
||||
def validate(self, data: Any, schema_name: str) -> bool:
|
||||
"""验证数据是否符合 schema"""
|
||||
if schema_name not in self._schemas:
|
||||
raise JsonCodecError(f"未知的 schema: {schema_name}")
|
||||
return self._check_schema(data, self._schemas[schema_name])
|
||||
|
||||
def _check_schema(self, data: Any, schema: dict) -> bool:
|
||||
"""检查 schema 匹配"""
|
||||
schema_type = schema.get("type")
|
||||
if schema_type == "object":
|
||||
if not isinstance(data, dict):
|
||||
return False
|
||||
required = schema.get("required", [])
|
||||
for field in required:
|
||||
if field not in data:
|
||||
return False
|
||||
properties = schema.get("properties", {})
|
||||
for key, value in data.items():
|
||||
if key in properties:
|
||||
if not self._check_schema(value, properties[key]):
|
||||
return False
|
||||
return True
|
||||
elif schema_type == "array":
|
||||
if not isinstance(data, list):
|
||||
return False
|
||||
items_schema = schema.get("items", {})
|
||||
return all(self._check_schema(item, items_schema) for item in data)
|
||||
elif schema_type == "string":
|
||||
return isinstance(data, str)
|
||||
elif schema_type == "number":
|
||||
return isinstance(data, (int, float))
|
||||
elif schema_type == "boolean":
|
||||
return isinstance(data, bool)
|
||||
return True
|
||||
|
||||
|
||||
class JsonCodecPlugin(Plugin):
|
||||
"""JSON 编解码器插件"""
|
||||
|
||||
def __init__(self):
|
||||
self.serializer = JsonSerializer()
|
||||
self.deserializer = JsonDeserializer()
|
||||
self.validator = JsonValidator()
|
||||
|
||||
def init(self, deps: dict = None):
|
||||
"""初始化"""
|
||||
pass
|
||||
|
||||
def start(self):
|
||||
"""启动"""
|
||||
print("[json-codec] JSON 编解码器已启动")
|
||||
|
||||
def stop(self):
|
||||
"""停止"""
|
||||
pass
|
||||
|
||||
def encode(self, data: Any, pretty: bool = False) -> str:
|
||||
"""编码 JSON"""
|
||||
return self.serializer.encode(data, pretty)
|
||||
|
||||
def decode(self, text: str) -> Any:
|
||||
"""解码 JSON"""
|
||||
return self.deserializer.decode(text)
|
||||
|
||||
def validate(self, data: Any, schema_name: str) -> bool:
|
||||
"""验证 JSON schema"""
|
||||
return self.validator.validate(data, schema_name)
|
||||
|
||||
def register_schema(self, name: str, schema: dict):
|
||||
"""注册 schema"""
|
||||
self.validator.register_schema(name, schema)
|
||||
|
||||
|
||||
# 注册类型
|
||||
register_plugin_type("JsonSerializer", JsonSerializer)
|
||||
register_plugin_type("JsonDeserializer", JsonDeserializer)
|
||||
register_plugin_type("JsonValidator", JsonValidator)
|
||||
register_plugin_type("JsonCodecError", JsonCodecError)
|
||||
|
||||
|
||||
def New():
|
||||
return JsonCodecPlugin()
|
||||
15
store/@{FutureOSS}/json-codec/manifest.json
Normal file
15
store/@{FutureOSS}/json-codec/manifest.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"metadata": {
|
||||
"name": "json-codec",
|
||||
"version": "1.0.0",
|
||||
"author": "FutureOSS",
|
||||
"description": "JSON 编解码器 - 插件间 JSON 数据处理和验证",
|
||||
"type": "utility"
|
||||
},
|
||||
"config": {
|
||||
"enabled": true,
|
||||
"args": {}
|
||||
},
|
||||
"dependencies": [],
|
||||
"permissions": []
|
||||
}
|
||||
Reference in New Issue
Block a user