# AI-Core 文档解析服务

基于 Python 和 Microsoft MarkItDown 的 gRPC 文档解析服务，支持多种文件格式转换为 Markdown。

## 特性

- **统一解析引擎** - 使用 Microsoft MarkItDown，一个库支持所有格式
- **支持格式广泛** - PDF、DOCX、DOC、PPTX、PPT、XLSX、XLS、CSV、图片、网页等
- **gRPC 接口** - 高性能、类型安全的 RPC 通信
- **依赖简单** - 只需安装 3 个核心包
- **易于部署** - 一键启动，开箱即用

## 项目结构

```
ai-core/
├── main.py                      # 服务启动入口
├── requirements.txt             # Python 依赖（仅 3 个包）
├── generate_grpc.py             # gRPC 代码生成脚本
├── start.sh                     # Linux/Mac 启动脚本
├── start.ps1                    # Windows 启动脚本
├── proto/                       # gRPC 协议定义
│   ├── document_parser.proto    # Protocol Buffers 定义
│   ├── document_parser_pb2.py  # 生成的 Python 代码
│   └── document_parser_pb2_grpc.py
├── parser/                      # 文档解析器模块
│   ├── __init__.py
│   └── parser.py               # MarkItDown 解析器
└── service/                     # gRPC 服务实现
    ├── __init__.py
    └── grpc_server.py           # gRPC 服务器
```

## 安装

### 1. 安装依赖

```bash
pip install -r requirements.txt
```

依赖包：
- `grpcio` - gRPC 框架
- `grpcio-tools` - gRPC 工具
- `grpcio-reflection` - gRPC 反射
- `protobuf` - Protocol Buffers
- `requests` - HTTP 请求
- `markitdown` - Microsoft 文档解析引擎

### 2. 生成 gRPC 代码

```bash
python generate_grpc.py
```

这会在 `proto` 目录下生成两个文件：
- `document_parser_pb2.py`
- `document_parser_pb2_grpc.py`

## 使用

### 方式 1: 使用启动脚本（推荐）

**Windows:**
```powershell
.\start.ps1
```

**Linux/Mac:**
```bash
bash start.sh
```

### 方式 2: 直接运行

```bash
python main.py --port 50051 --max-workers 10
```

参数说明：
- `--port`: gRPC 服务端口（默认 50051）
- `--max-workers`: 最大工作线程数（默认 10）
- `--log-level`: 日志级别（DEBUG/INFO/WARNING/ERROR，默认 INFO）

## gRPC 接口

### ParseDocument

解析文档为 Markdown

```protobuf
message ParseRequest {
  string file_url = 1;                    // 文件 URL（必填）
  string file_name = 2;                   // 文件名（必填）
  string file_type = 3;                   // 文件类型（可选）
  string parser_engine = 4;               // 解析引擎（可选）
  map<string, string> engine_overrides = 5;// 引擎参数覆盖（可选）
}

message ParseResponse {
  bool success = 1;                       // 是否成功
  string content = 2;                      // Markdown 内容
  string message = 3;                      // 消息
  int32 content_length = 4;              // 内容长度
  string file_type = 5;                   // 文件类型
  string parser_engine = 6;               // 使用的解析引擎
}
```

### GetSupportedFormats

获取支持的文件格式列表

### GetEngines

获取可用的解析引擎列表

## Go 客户端调用示例

```go
import (
    "context"
    "log"
    
    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials/insecure"
)

func main() {
    conn, err := grpc.Dial("localhost:50051", grpc.WithTransportCredentials(insecure.NewCredentials()))
    if err != nil {
        log.Fatalf("Failed to connect: %v", err)
    }
    defer conn.Close()

    client := docparser.NewDocumentParserClient(conn)

    resp, err := client.ParseDocument(context.Background(), &docparser.ParseRequest{
        FileUrl:   "http://localhost:8082/files/abc123.pdf",
        FileName:  "example.pdf",
        FileType:  "pdf",
    })

    if err != nil {
        log.Fatalf("Failed to parse: %v", err)
    }

    log.Printf("Success: %v", resp.Success)
    log.Printf("Content length: %d", resp.ContentLength)
    log.Printf("Markdown content:\n%s", resp.Content)
}
```

## 支持的文件格式

| 类别 | 支持的扩展名 |
|------|-------------|
| **文档** | pdf, docx, doc, pptx, ppt |
| **表格** | xlsx, xls, csv |
| **文本** | md, markdown, txt |
| **图片** | jpg, jpeg, png, gif, bmp, tiff, webp |
| **网页** | html, htm |

## 为什么选择 MarkItDown？

1. **微软官方支持** - Microsoft 开发，持续维护
2. **格式覆盖全** - 一个库支持所有常见格式
3. **统一接口** - 无需为每种格式单独实现
4. **安装简单** - 只需 `pip install markitdown`
5. **性能优秀** - 基于优化的解析算法

## 故障排查

### 端口已被占用

如果提示端口 50051 已被占用，可以更换端口：

```bash
python main.py --port 50052
```

### gRPC 代码未生成

如果提示找不到 `docparser_pb2`，运行：

```bash
python generate_grpc.py
```

### 依赖安装失败

确保使用 Python 3.8+：

```bash
python --version
pip --version
```

## 开发

### 测试解析器

```python
from parser import Parser

parser = Parser()

# 解析文件
result = parser.parse("path/to/file.pdf")
print(result["content"])

# 解析字节内容
with open("file.pdf", "rb") as f:
    content = f.read()
result = parser.parse_bytes(content, "file.pdf")
print(result["content"])
```

## 许可证

MIT License
