caicai-codeindex 0.3.4
CodeIndex Python SDK - Direct SQLite database access
License: MIT
Requires Python: >=3.9
Keywords: codeindex, ast, code-index, tree-sitter, code-intelligence, semantic-search, sqlite

# CodeIndex Python SDK

[![Python Version](https://img.shields.io/badge/python-%3E%3D3.9-blue.svg)](https://www.python.org/downloads/)
[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)

直接访问 CodeIndex SQLite 数据库的 Python SDK，无需 Node.js 运行时。

## ✨ 主要特性

- ✅ **无需 Node.js**：直接读取 SQLite 数据库，无需启动 Node.js 进程
- ✅ **性能卓越**：无进程间通信开销，查询延迟从 50-100ms 降至 1-5ms
- ✅ **简单易用**：API 清晰直观，保持向后兼容
- ✅ **类型提示**：完整的类型定义，IDE 友好
- ✅ **轻量级**：仅依赖 numpy 和 requests
- ✅ **自然语言查询**：支持使用自然语言进行语义搜索，自动生成 embedding

## 📦 安装

### 从 PyPI 安装（推荐）

```bash
# 使用阿里云镜像源（推荐，速度更快）
pip install -i https://mirrors.aliyun.com/pypi/simple/ caicai-codeindex

# 或使用官方 PyPI 源
pip install caicai-codeindex
```

### 本地开发安装

```bash
cd sdk/python
pip install -e .
```

## 🚀 快速开始

### 前置要求

在使用 SDK 之前，需要先使用 CodeIndex CLI 构建索引数据库：

```bash
node dist/src/cli/index.js index \
  --root /path/to/your/project \
  --db .codeindex/project.db \
  --lang go
```

### 基本使用

```python
from codeindex_sdk import CodeIndexClient

# 方式1：直接使用数据库路径（推荐）
with CodeIndexClient(".codeindex/project.db") as client:
    # 查找符号
    symbols = client.find_symbols(name="CreateUser", language="go")
    for symbol in symbols:
        print(f"{symbol['name']} at {symbol['location']['path']}:{symbol['location']['startLine']}")
    
    # 查找单个符号
    symbol = client.find_symbol("CreateUser", language="go")
    if symbol:
        print(f"Found: {symbol['qualifiedName']}")
    
    # 查询对象属性
    props = client.object_properties("UserService", language="go")
    for prop in props:
        print(f"{prop['kind']} {prop['name']}")
    
    # 生成调用链
    chain = client.call_chain(from_symbol=12345, direction="forward", depth=3)
    if chain:
        print(f"Call chain: {chain['name']} -> {len(chain.get('children', []))} calls")
    
    # 获取定义位置
    location = client.definition(12345)
    if location:
        print(f"Definition: {location['path']}:{location['startLine']}")
    
    # 获取引用
    refs = client.references(12345)
    print(f"Found {len(refs)} references")
```

### 使用配置对象（向后兼容）

```python
from codeindex_sdk import CodeIndexClient, CodeIndexConfig

# 方式2：使用配置对象（向后兼容）
config = CodeIndexConfig(
    db_path=".codeindex/project.db",
    # 以下参数已废弃，但保留用于兼容性
    root_dir="/path/to/project",
    languages=["go", "ts"],
)

with CodeIndexClient(config) as client:
    symbols = client.find_symbols(name="CreateUser", language="go")
```

### 语义搜索（自然语言查询）

语义搜索功能支持使用自然语言查询代码，类似于 Node.js CLI 的 `search` 命令。

#### 前置要求

1. 使用 CLI 生成 embedding：
```bash
node dist/cli/index.js embed --db .codeindex/project.db
```

2. 配置 embedding API（三种方式）：
   - **方式1（推荐）**：在 `codeindex.config.json` 中配置：
   ```json
   {
     "embedding": {
       "apiEndpoint": "https://api.example.com/v1/embeddings",
       "apiKey": "your-api-key",
       "model": "bge-m3",
       "dimension": 1024,
       "defaultModel": "bge-m3"
     }
   }
   ```
   
   - **方式2**：使用环境变量：
   ```bash
   export CODEINDEX_EMBEDDING_API_ENDPOINT="https://api.example.com/v1/embeddings"
   export CODEINDEX_EMBEDDING_API_KEY="your-api-key"
   ```
   
   - **方式3**：在代码中直接传递参数

#### 使用示例

**最简单的用法（推荐）**：
```python
from codeindex import CodeIndexClient

with CodeIndexClient(".codeindex/project.db") as client:
    # 自然语言查询，自动从配置文件读取 embedding 配置
    results = client.semantic_search(
        query="用户登录验证",
        top_k=5
    )
    
    for result in results:
        symbol = result['symbol']
        print(f"{symbol['kind']} {symbol['qualifiedName']}")
        print(f"  相似度: {result['similarity']:.1%}")
        print(f"  位置: {result['location']['path']}:{result['location']['startLine']}")
        if symbol.get('chunkSummary'):
            print(f"  摘要: {symbol['chunkSummary'][:80]}...")
        print()
```

**带过滤条件的查询**：
```python
results = client.semantic_search(
    query="用户登录验证",
    top_k=5,
    language="go",  # 只搜索 Go 代码
    kind="function",  # 只搜索函数
    min_similarity=0.7  # 最小相似度阈值
)
```

**显式指定 embedding 配置**：
```python
results = client.semantic_search(
    query="用户登录验证",
    api_endpoint="https://api.example.com/v1/embeddings",
    api_key="your-api-key",
    model="bge-m3",
    top_k=5
)
```

**使用预计算的 embedding**（高级用法）：
```python
import openai

# 手动生成 embedding
response = openai.embeddings.create(
    model="text-embedding-3-small",
    input="用户登录验证"
)
query_embedding = response.data[0].embedding

# 使用预计算的 embedding
results = client.semantic_search(
    query="用户登录验证",
    query_embedding=query_embedding,
    model="text-embedding-3-small",
    top_k=5
)
```

## 📚 API 文档

### CodeIndexClient

主要的客户端类，用于与 CodeIndex 数据库交互。

#### 初始化

```python
CodeIndexClient(db_path: str | CodeIndexConfig, **kwargs)
```

**参数：**
- `db_path` (str | CodeIndexConfig): 数据库文件路径或配置对象
- `**kwargs`: 其他参数（已废弃，忽略）

**示例：**
```python
# 使用路径
client = CodeIndexClient(".codeindex/project.db")

# 使用配置对象
config = CodeIndexConfig(db_path=".codeindex/project.db")
client = CodeIndexClient(config)
```

#### 查找符号

##### `find_symbols(name: str, language: str | None = None) -> List[Dict]`

查找所有匹配名称的符号。

**参数：**
- `name` (str): 符号名称
- `language` (str, optional): 语言过滤器（如 "go", "ts", "python"）

**返回：** 符号字典列表，每个字典包含：
- `symbolId`: 符号 ID
- `name`: 符号名称
- `kind`: 符号类型
- `qualifiedName`: 限定名
- `location`: 位置信息（path, startLine, endLine 等）

**示例：**
```python
symbols = client.find_symbols(name="CreateUser", language="go")
```

##### `find_symbol(name: str, language: str | None = None, in_file: str | None = None, kind: str | None = None) -> Dict | None`

查找单个匹配条件的符号。

**参数：**
- `name` (str): 符号名称
- `language` (str, optional): 语言过滤器
- `in_file` (str, optional): 文件路径过滤器
- `kind` (str, optional): 符号类型过滤器（如 "function", "class", "struct"）

**返回：** 符号字典或 None

**示例：**
```python
symbol = client.find_symbol(name="CreateUser", language="go", kind="function")
```

#### 对象属性

##### `object_properties(object_name: str, language: str | None = None) -> List[Dict]`

获取对象/类/结构体的属性和方法。

**参数：**
- `object_name` (str): 对象名称
- `language` (str, optional): 语言过滤器

**返回：** 属性字典列表，每个字典包含：
- `name`: 属性/方法名称
- `kind`: 类型（如 "method", "field", "property"）
- `signature`: 签名信息

**示例：**
```python
props = client.object_properties("UserService", language="go")
```

#### 调用链

##### `call_chain(from_symbol: int, direction: str = "forward", depth: int = 5) -> Dict | None`

构建调用链。

**参数：**
- `from_symbol` (int): 起始符号 ID
- `direction` (str): "forward"（向前，调用谁）或 "backward"（向后，被谁调用）
- `depth` (int): 最大深度

**返回：** 调用链字典或 None，包含：
- `name`: 符号名称
- `depth`: 当前深度
- `children`: 子节点列表

**示例：**
```python
chain = client.call_chain(from_symbol=12345, direction="forward", depth=3)
```

#### 定义和引用

##### `definition(symbol_id: int) -> Dict | None`

获取符号的定义位置。

**参数：**
- `symbol_id` (int): 符号 ID

**返回：** 位置字典或 None，包含 path、startLine、endLine 等

**示例：**
```python
location = client.definition(12345)
```

##### `references(symbol_id: int) -> List[Dict]`

获取符号的所有引用。

**参数：**
- `symbol_id` (int): 符号 ID

**返回：** 引用位置字典列表

**示例：**
```python
refs = client.references(12345)
```

#### 语义搜索

##### `semantic_search(query: str | None = None, query_embedding: List[float] | None = None, model: str | None = None, top_k: int = 10, language: str | None = None, kind: str | None = None, min_similarity: float = 0.7, api_endpoint: str | None = None, api_key: str | None = None, dimension: int | None = None) -> List[Dict]`

语义搜索，支持自然语言查询。

**参数：**
- `query` (str, optional): 自然语言查询文本（如果未提供 `query_embedding`，则必需）
- `query_embedding` (List[float], optional): 查询 embedding 向量（如果未提供，将从 `query` 自动生成）
- `model` (str, optional): Embedding 模型名称（可选，将从配置文件读取）
- `top_k` (int): 返回结果数量，默认 10
- `language` (str, optional): 语言过滤器（如 "go", "ts", "python"）
- `kind` (str, optional): 符号类型过滤器（如 "function", "class", "struct"）
- `min_similarity` (float): 最小相似度阈值（0.0-1.0），默认 0.7
- `api_endpoint` (str, optional): Embedding API 端点（可选，将从配置文件读取）
- `api_key` (str, optional): Embedding API 密钥（可选，将从配置文件读取）
- `dimension` (int, optional): Embedding 维度（可选，将从配置文件读取）

**返回：** 搜索结果列表，每个结果包含：
- `symbol`: 符号信息（包含 name, kind, qualifiedName, chunkSummary 等）
- `similarity`: 相似度分数（0.0-1.0）
- `location`: 位置信息（path, startLine, endLine 等）

**配置优先级：**
1. 函数参数（最高优先级）
2. 环境变量（`CODEINDEX_EMBEDDING_API_ENDPOINT`, `CODEINDEX_EMBEDDING_API_KEY`, `CODEINDEX_EMBEDDING_MODEL`）
3. `codeindex.config.json` 配置文件
4. 默认值

**示例：**
```python
# 自然语言查询（推荐）
results = client.semantic_search(
    query="用户登录验证",
    top_k=5
)

# 带过滤条件
results = client.semantic_search(
    query="用户登录验证",
    top_k=5,
    language="go",
    kind="function",
    min_similarity=0.7
)

# 使用预计算的 embedding
results = client.semantic_search(
    query="用户登录验证",
    query_embedding=embedding_vector,
    model="text-embedding-3-small",
    top_k=5
)
```

## ⚙️ 工作原理

1. **索引构建**：使用 CodeIndex CLI（TypeScript）构建索引数据库
2. **数据库查询**：Python SDK 直接读取 SQLite 数据库
3. **无需 Node.js**：完全独立于 Node.js 运行时

```
┌─────────────────┐         ┌──────────────┐         ┌─────────────┐
│  CodeIndex CLI  │ ──────> │  SQLite DB   │ <────── │ Python SDK  │
│   (TypeScript)  │ 构建索引  │  (.codeindex) │  查询   │  (本 SDK)   │
└─────────────────┘         └──────────────┘         └─────────────┘
```

## 🔄 从旧版本迁移

### 旧版本（0.1.x）

```python
from codeindex_sdk import CodeIndexClient, CodeIndexConfig

config = CodeIndexConfig(
    root_dir="/path/to/project",
    db_path=".codeindex/project.db",
    languages=["go", "ts"],
)

with CodeIndexClient(config) as client:
    symbols = client.find_symbols(name="CreateUser", language="go")
```

### 新版本（0.2.x）

```python
from codeindex_sdk import CodeIndexClient

# 简化：只需数据库路径
with CodeIndexClient(".codeindex/project.db") as client:
    symbols = client.find_symbols(name="CreateUser", language="go")
```

**注意**：旧版本代码无需修改即可运行（向后兼容），但建议更新为新 API。

## 🆚 性能对比

| 指标 | 旧版本（Node Worker） | 新版本（直接 DB） | 提升 |
|------|---------------------|------------------|------|
| 启动时间 | ~500ms | ~10ms | **50x** |
| 查询延迟 | 50-100ms | 1-5ms | **20x** |
| 内存占用 | Node + Python | 仅 Python | **减少 ~50MB** |
| 依赖要求 | Node.js + Python | 仅 Python | **简化** |

## 🐛 常见问题

### Q: 数据库文件不存在？

**A:** 请先使用 CodeIndex CLI 构建索引：

```bash
node dist/src/cli/index.js index \
  --root /path/to/project \
  --db .codeindex/project.db \
  --lang go
```

### Q: 语义搜索返回空结果？

**A:** 确保：
1. 已使用 CLI 生成 embedding：`node dist/cli/index.js embed --db .codeindex/project.db`
2. 使用相同的 embedding 模型（可通过配置文件或参数指定）
3. 检查 `min_similarity` 阈值是否过高（尝试降低到 0.5 或更低）
4. 确保已正确配置 embedding API（配置文件或环境变量）

### Q: 如何配置 embedding API？

**A:** 有三种方式（按优先级排序）：

1. **环境变量（推荐）**：
```bash
export CODEINDEX_EMBEDDING_API_ENDPOINT="https://api.example.com/v1/embeddings"
export CODEINDEX_EMBEDDING_API_KEY="your-api-key"
export CODEINDEX_EMBEDDING_MODEL="bge-m3"  # 可选
```

2. **配置文件**：在项目根目录创建 `codeindex.config.json`：
```json
{
  "embedding": {
    "apiEndpoint": "https://api.example.com/v1/embeddings",
    "apiKey": "your-api-key",
    "model": "bge-m3",
    "defaultModel": "bge-m3"
  }
}
```

3. **代码中传递**：
```python
results = client.semantic_search(
    query="用户登录验证",
    api_endpoint="https://api.example.com/v1/embeddings",
    api_key="your-api-key",
    model="bge-m3"
)
```

### Q: 如何生成 query_embedding？

**A:** 通常不需要手动生成！直接使用自然语言查询即可：

```python
# 推荐：直接使用自然语言查询
results = client.semantic_search(query="用户登录验证", top_k=5)
```

SDK 会自动调用 embedding API 生成查询向量。如果需要手动生成（高级用法），可以使用你选择的 embedding API（如 OpenAI）：

```python
import openai

response = openai.embeddings.create(
    model="text-embedding-3-small",  # 与索引时使用的模型一致
    input="你的查询文本"
)
query_embedding = response.data[0].embedding

# 然后传递给 semantic_search
results = client.semantic_search(
    query="你的查询文本",
    query_embedding=query_embedding,
    model="text-embedding-3-small"
)
```

### Q: 支持哪些编程语言？

**A:** 支持 CodeIndex CLI 支持的所有语言，包括：
- Go
- TypeScript/JavaScript
- Python
- Java
- Rust
- HTML

具体支持情况请参考 [CodeIndex 语言支持文档](../../docs/language-support.md)。

### Q: 如何处理并发访问？

**A:** SQLite 支持多读单写。多个 Python 进程可以同时读取数据库，但写入操作（如索引更新）需要独占访问。建议：
- 读取操作：可以并发
- 索引更新：在更新期间避免读取操作

## 📋 系统要求

- **Python**: >= 3.9
- **索引数据库**：需要先使用 CodeIndex CLI 构建索引
- **依赖**: numpy >= 1.24.0, requests >= 2.28.0

## 📄 许可证

MIT License

## 🔗 相关链接

- [CodeIndex 主项目](https://github.com/LydiaCai1203/codeindex)
- [问题反馈](https://github.com/LydiaCai1203/codeindex/issues)
- [语言支持文档](../../docs/language-support.md)

## 📝 更新日志

### v0.3.0
- ✨ 新增自然语言查询功能，支持直接使用自然语言进行语义搜索
- ✨ 自动从配置文件读取 embedding API 配置
- ✨ 支持环境变量配置 embedding API
- 🔧 改进 `semantic_search` API，自动生成查询 embedding

### v0.2.0
- ✨ 重构为直接访问 SQLite 数据库，无需 Node.js
- ⚡ 性能大幅提升（启动时间 50x，查询延迟 20x）
- 🔄 保持向后兼容性

### v0.1.x
- 初始版本，通过 Node.js Worker 进程访问