lightpdf-aipdf-mcp 0.1.149__py3-none-any.whl → 0.1.150__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lightpdf_aipdf_mcp/__init__.py +2 -2
- lightpdf_aipdf_mcp/api/__init__.py +6 -0
- lightpdf_aipdf_mcp/api/adapter.py +193 -0
- lightpdf_aipdf_mcp/api/server.py +714 -0
- lightpdf_aipdf_mcp/core/__init__.py +1 -0
- lightpdf_aipdf_mcp/core/processor.py +460 -0
- lightpdf_aipdf_mcp/models/__init__.py +1 -0
- lightpdf_aipdf_mcp/models/schemas.py +9 -0
- lightpdf_aipdf_mcp/services/__init__.py +1 -0
- lightpdf_aipdf_mcp/{converter.py → services/converter.py} +44 -6
- lightpdf_aipdf_mcp/{create_pdf.py → services/create_pdf.py} +2 -1
- lightpdf_aipdf_mcp/{editor.py → services/editor.py} +2 -5
- lightpdf_aipdf_mcp/{ocr.py → services/ocr.py} +2 -5
- lightpdf_aipdf_mcp/{summarizer.py → services/summarizer.py} +2 -5
- lightpdf_aipdf_mcp/{translator.py → services/translator.py} +2 -5
- lightpdf_aipdf_mcp/utils/__init__.py +1 -0
- lightpdf_aipdf_mcp/{common.py → utils/common.py} +61 -1
- lightpdf_aipdf_mcp-0.1.150.dist-info/METADATA +199 -0
- lightpdf_aipdf_mcp-0.1.150.dist-info/RECORD +21 -0
- lightpdf_aipdf_mcp/server.py +0 -1718
- lightpdf_aipdf_mcp-0.1.149.dist-info/METADATA +0 -305
- lightpdf_aipdf_mcp-0.1.149.dist-info/RECORD +0 -13
- {lightpdf_aipdf_mcp-0.1.149.dist-info → lightpdf_aipdf_mcp-0.1.150.dist-info}/WHEEL +0 -0
- {lightpdf_aipdf_mcp-0.1.149.dist-info → lightpdf_aipdf_mcp-0.1.150.dist-info}/entry_points.txt +0 -0
lightpdf_aipdf_mcp/__init__.py
CHANGED
@@ -0,0 +1,193 @@
|
|
1
|
+
"""FastMCP适配层 - 连接FastMCP和现有业务逻辑"""
|
2
|
+
import json
|
3
|
+
from typing import List, Dict, Any, Optional
|
4
|
+
from urllib.request import url2pathname
|
5
|
+
|
6
|
+
from fastmcp import Context
|
7
|
+
from ..utils.common import Logger, FileHandler, BaseResult
|
8
|
+
from ..models.schemas import FileObject
|
9
|
+
|
10
|
+
|
11
|
+
class FastMCPLogger:
|
12
|
+
"""FastMCP Logger适配器"""
|
13
|
+
def __init__(self, context: Context):
|
14
|
+
self.context = context
|
15
|
+
self._info_log = []
|
16
|
+
|
17
|
+
async def log(self, level: str, message: str, add_to_result: bool = True):
|
18
|
+
"""记录日志消息"""
|
19
|
+
if add_to_result:
|
20
|
+
self._info_log.append(message)
|
21
|
+
|
22
|
+
if level.lower() == "error":
|
23
|
+
await self.context.error(message)
|
24
|
+
elif level.lower() == "warning":
|
25
|
+
# FastMCP Context 可能没有warning方法,使用info代替
|
26
|
+
await self.context.info(f"⚠️ {message}")
|
27
|
+
elif level.lower() == "debug":
|
28
|
+
# 只在debug模式下输出
|
29
|
+
import os
|
30
|
+
if os.getenv("DEBUG"):
|
31
|
+
await self.context.info(f"🐛 {message}")
|
32
|
+
else:
|
33
|
+
await self.context.info(message)
|
34
|
+
|
35
|
+
async def error(self, message: str, error_class=RuntimeError):
|
36
|
+
"""记录错误并引发异常"""
|
37
|
+
await self.log("error", message)
|
38
|
+
raise error_class(message)
|
39
|
+
|
40
|
+
def get_result_info(self) -> List[str]:
|
41
|
+
"""获取收集的信息日志"""
|
42
|
+
return self._info_log
|
43
|
+
|
44
|
+
|
45
|
+
def convert_file_objects(files: List[FileObject]) -> List[Dict[str, str]]:
|
46
|
+
"""转换FastMCP文件对象为原有格式"""
|
47
|
+
file_objects = []
|
48
|
+
for file_obj in files:
|
49
|
+
converted = {"path": file_obj.path}
|
50
|
+
|
51
|
+
# 处理file://协议
|
52
|
+
if file_obj.path.startswith("file://"):
|
53
|
+
converted["path"] = url2pathname(file_obj.path.removeprefix('file:'))
|
54
|
+
|
55
|
+
if file_obj.password:
|
56
|
+
converted["password"] = file_obj.password
|
57
|
+
if file_obj.name:
|
58
|
+
converted["name"] = file_obj.name
|
59
|
+
|
60
|
+
file_objects.append(converted)
|
61
|
+
|
62
|
+
return file_objects
|
63
|
+
|
64
|
+
|
65
|
+
def generate_operation_config(
|
66
|
+
operation_type: str,
|
67
|
+
format_value: Optional[str] = None,
|
68
|
+
extra_params: Optional[Dict[str, Any]] = None,
|
69
|
+
edit_type: Optional[str] = None
|
70
|
+
) -> Dict[str, Any]:
|
71
|
+
"""生成操作配置字典"""
|
72
|
+
config = {}
|
73
|
+
|
74
|
+
# 设置操作类型
|
75
|
+
if operation_type == "convert":
|
76
|
+
config["is_edit_operation"] = False
|
77
|
+
if format_value:
|
78
|
+
config["format"] = format_value
|
79
|
+
elif operation_type == "edit":
|
80
|
+
config["is_edit_operation"] = True
|
81
|
+
if edit_type:
|
82
|
+
config["edit_type"] = edit_type
|
83
|
+
elif operation_type == "translate":
|
84
|
+
config["is_translate_operation"] = True
|
85
|
+
elif operation_type == "ocr":
|
86
|
+
config["is_ocr_operation"] = True
|
87
|
+
elif operation_type == "summarize":
|
88
|
+
config["is_summarize_operation"] = True
|
89
|
+
|
90
|
+
# 设置额外参数
|
91
|
+
if extra_params:
|
92
|
+
config["extra_params"] = extra_params
|
93
|
+
|
94
|
+
return config
|
95
|
+
|
96
|
+
|
97
|
+
async def process_tool_call_adapter(
|
98
|
+
context: Context,
|
99
|
+
file_objects: List[FileObject],
|
100
|
+
operation_config: Dict[str, Any]
|
101
|
+
) -> str:
|
102
|
+
"""适配原有的process_tool_call函数"""
|
103
|
+
from ..core.processor import process_tool_call
|
104
|
+
|
105
|
+
# 创建适配的logger
|
106
|
+
logger = FastMCPLogger(context)
|
107
|
+
|
108
|
+
# 转换文件对象格式
|
109
|
+
converted_files = convert_file_objects(file_objects)
|
110
|
+
|
111
|
+
# 调用原有函数
|
112
|
+
result = await process_tool_call(logger, converted_files, operation_config)
|
113
|
+
|
114
|
+
# 返回文本内容
|
115
|
+
return result.text
|
116
|
+
|
117
|
+
|
118
|
+
|
119
|
+
|
120
|
+
|
121
|
+
async def create_pdf_adapter(
|
122
|
+
context: Context,
|
123
|
+
prompt: str,
|
124
|
+
filename: str,
|
125
|
+
language: str,
|
126
|
+
enable_web_search: bool = False
|
127
|
+
) -> str:
|
128
|
+
"""适配PDF创建功能"""
|
129
|
+
from ..services.create_pdf import PDFCreator
|
130
|
+
from ..utils.common import FileHandler
|
131
|
+
|
132
|
+
# 创建适配的logger和file_handler
|
133
|
+
logger = FastMCPLogger(context)
|
134
|
+
file_handler = FileHandler(logger)
|
135
|
+
|
136
|
+
# 创建PDF创建器
|
137
|
+
pdf_creator = PDFCreator(logger, file_handler)
|
138
|
+
|
139
|
+
# 调用创建方法
|
140
|
+
result = await pdf_creator.create_pdf_from_prompt(
|
141
|
+
prompt=prompt,
|
142
|
+
language=language,
|
143
|
+
enable_web_search=enable_web_search,
|
144
|
+
original_name=filename
|
145
|
+
)
|
146
|
+
|
147
|
+
# 生成报告
|
148
|
+
from ..core.processor import generate_result_report
|
149
|
+
return generate_result_report([result])
|
150
|
+
|
151
|
+
|
152
|
+
async def merge_pdfs_adapter(
|
153
|
+
context: Context,
|
154
|
+
files: List[FileObject]
|
155
|
+
) -> str:
|
156
|
+
"""适配PDF合并功能"""
|
157
|
+
from ..services.editor import Editor
|
158
|
+
from ..utils.common import FileHandler
|
159
|
+
|
160
|
+
# 创建适配的logger和file_handler
|
161
|
+
logger = FastMCPLogger(context)
|
162
|
+
file_handler = FileHandler(logger)
|
163
|
+
|
164
|
+
# 创建编辑器
|
165
|
+
editor = Editor(logger, file_handler)
|
166
|
+
|
167
|
+
# 转换文件对象
|
168
|
+
file_paths = [file_obj.path for file_obj in files]
|
169
|
+
passwords = [file_obj.password for file_obj in files if file_obj.password]
|
170
|
+
original_names = [file_obj.name for file_obj in files if file_obj.name]
|
171
|
+
|
172
|
+
# 处理file://协议
|
173
|
+
for i, path in enumerate(file_paths):
|
174
|
+
if path.startswith("file://"):
|
175
|
+
file_paths[i] = url2pathname(path.removeprefix('file:'))
|
176
|
+
|
177
|
+
# 使用第一个非空密码
|
178
|
+
password = passwords[0] if passwords else None
|
179
|
+
|
180
|
+
# 合并文件名
|
181
|
+
merged_name = None
|
182
|
+
if original_names:
|
183
|
+
if len(original_names) == 1:
|
184
|
+
merged_name = original_names[0]
|
185
|
+
else:
|
186
|
+
merged_name = f"{original_names[0]}_{original_names[1]}_等"
|
187
|
+
|
188
|
+
# 调用合并方法
|
189
|
+
result = await editor.merge_pdfs(file_paths, password, merged_name)
|
190
|
+
|
191
|
+
# 生成报告
|
192
|
+
from ..core.processor import generate_result_report
|
193
|
+
return generate_result_report([result])
|