按需查阅，不是必读接入步骤。接入路线：[查询取数接入路线](/docs)

# 查询 SDK（Python 与 Go）

使用 Consumer API Key 查询数据。没有 Key 时，先在 [Portal](/docs/portal) 申请应用订阅与密钥。
下载不需要管理员登录；API 调用仍受应用权限约束。

## Python

需要 Python 3.10 或更新版本：


```bash
curl -fsSL https://www.marsyoo.com/api/sdk/python-consumer \
  -o marsyoo-python-consumer-sdk-v0.2.0.tar.gz
tar -xzf marsyoo-python-consumer-sdk-v0.2.0.tar.gz
cd marsyoo-python-consumer-sdk-v0.2.0
python3 -m venv .venv
. .venv/bin/activate
python -m pip install .
```


将应用密钥放入 `WHALE_API_KEY` 环境变量，再执行：


```python
import os
from whale_consumer import Client

client = Client(api_key=os.environ["WHALE_API_KEY"], timeout=30)
result = client.search(query="人工智能", mode="keyword", limit=10)
for item in result.get("results", []):
    document_id = item["document_id"]
    content = client.get_document_content(document_id)
    print(document_id, content.get("content", {}).get("body", ""))
```


`results=[]` 表示本次没有匹配结果，不会自动采集。当前 Python 包只提供消费 API，不包含采集器模块。

## Go

[下载 Go Consumer SDK](/api/sdk/go-consumer)，解压并在包目录运行 `go test ./...`。
在你的 Go 应用中使用本地模块路径：


```bash
go mod edit -require=whale/sdk/go/consumer@v0.0.0
go mod edit -replace=whale/sdk/go/consumer=/absolute/path/to/marsyoo-go-consumer-sdk-v0.2.0
```


将解压路径替换为实际绝对路径。模块的 README 包含查询与变化订阅示例；导入路径为 `whale/sdk/go/consumer`。

以下示例可放入应用的 `main.go`：


```go
package main

import (
    "context"
    "fmt"
    "log"
    "os"
    "time"

    consumer "whale/sdk/go/consumer"
)

func main() {
    key := os.Getenv("WHALE_API_KEY")
    if key == "" {
        log.Fatal("Set WHALE_API_KEY")
    }
    ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
    defer cancel()
    client := consumer.New("https://www.marsyoo.com", key)
    result, err := client.Search(ctx, consumer.SearchRequest{Query: "AI", Mode: "keyword", Limit: 10})
    if err != nil {
        log.Fatal(err)
    }
    for _, item := range result.Results {
        content, err := client.GetDocumentContent(ctx, item.DocumentID, "")
        if err != nil {
            log.Fatal(err)
        }
        fmt.Println(item.DocumentID, content.Content["body"])
    }
}
```


加入代码后执行 `go mod tidy`，再执行 `go run .`。没有匹配结果时不会请求正文接口。

## 按话题或分类获取内容


```python
page = client.browse_documents(
    dataset_id="social_media_raw",
    topics=["AI"],
    created_from="2026-10-01T00:00:00Z",
    created_to="2026-10-02T00:00:00Z",
    limit=50,
)
for item in page.get("documents", []):
    print(item["document"]["id"])
```


后续页保持参数不变，并传入返回的 `next_cursor` 为 `cursor`。Python 还提供 `get_user`、`list_user_documents`、`list_classifications`、`search_history`；Go 对应 `GetUser`、`ListUserDocuments`、`ListClassifications`、`SearchHistory`、`BrowseDocuments` 与 `CatalogRequest`。检索可传 `query_vector` / `QueryVector`；检索 `cursor` / `Cursor` 仅限 keyword 模式。用户资料是已有采集观察，不是实时平台用户档案。

## 方法一览

| 用途 | Python | Go | 对应接口 |
| --- | --- | --- | --- |
| 检索 | `search` | `Search` | `POST /v1/search` |
| 历史检索 | `search_history` | `SearchHistory` | `POST /v1/search/history` |
| 按条件筛选内容 | `browse_documents` | `BrowseDocuments` | `GET /v1/documents/browse` |
| 读取用户资料 | `get_user` | `GetUser` | `GET /v1/users/{platform}/{id}` |
| 读取用户的内容 | `list_user_documents` | `ListUserDocuments` | `GET /v1/users/{platform}/{id}/documents` |
| 查询分类字典 | `list_classifications` | `ListClassifications` | `GET /v1/classifications` |
| 读取文档元数据 | `get_document` | `GetDocument` | `GET /v1/documents/{id}` |
| 读取完整正文 | `get_document_content` | `GetDocumentContent` | `GET /v1/documents/{id}/content` |
| 批量读取 | `batch_get` | `BatchGet` | `POST /v1/documents/batch-get` |
| 正文版本历史 | `list_document_versions` | `ListDocumentVersions` | `GET /v1/documents/{id}/versions` |
| 指标快照历史 | `list_document_snapshots` | `ListDocumentSnapshots` | `GET /v1/documents/{id}/snapshots` |
| 字幕、OCR 等片段 | `list_document_parts` | `ListDocumentParts` | `GET /v1/documents/{id}/parts` |
| 结构化事实 | `list_document_facts` | `ListDocumentFacts` | `GET /v1/documents/{id}/facts` |
| 附件列表与下载链接 | `list_attachments`、`get_attachment_download_url` | `ListAttachments`、`GetAttachmentDownloadURL` | `GET /v1/documents/{id}/attachments…` |
| 增量同步 | `list_changes`、`iter_change_pages` | `ListChanges`、`NewChangesIterator` | `GET /v1/changes` |
| 按需采集 | `create_live_query`、`get_live_query`、`list_live_query_results`、`cancel_live_query` | `CreateLiveQuery`、`GetLiveQuery`、`ListLiveQueryResults`、`CancelLiveQuery` | `/v1/live-queries…` |
| 定期采集 | `create_collection_subscription`、`list_collection_subscriptions`、`pause_…`/`resume_collection_subscription`、`list_collection_subscription_tasks` | `CreateCollectionSubscription`、`ListCollectionSubscriptions`、`Pause…`/`ResumeCollectionSubscription`、`ListCollectionSubscriptionTasks` | `/v1/collection/subscriptions…` |
| 批量导出 | `create_export`、`get_export`、`list_export_files`、`download_export_file`、`cancel_export` | `CreateExport`、`GetExport`、`ListExportFiles`、`DownloadExportFile`、`CancelExport` | `/v1/exports…` |
| 分析任务（Preview） | `create_analysis_run`、`get_analysis_run`、`cancel_analysis_run`、`list_analysis_artifacts`、`download_analysis_artifact`，以及 `*_analysis_subscription*`、`get_analysis_checkpoint` | `CreateAnalysisRun`、`GetAnalysisRun`、`CancelAnalysisRun`、`ListAnalysisArtifacts`、`DownloadAnalysisArtifact`，以及 `*AnalysisSubscription*`、`GetAnalysisCheckpoint` | `/v1/analysis…` |

下载文件的方法（`download_export_file`、`download_analysis_artifact` 及 Go 对应方法）以流式写入，不会把整个文件读入内存。附件下载链接是 300 秒有效的签名 URL，直接下载，不要携带 API Key。

## 错误、重试与超时

- 接口返回非 2xx 时抛出或返回 `APIError`，包含 `code`、`message` 和 HTTP 状态（Python 为 `status`，Go 为 `Status`）。错误码含义见[限流、重试与排错](/docs/production)。
- 只有增量同步（`list_changes` / `ListChanges` 及其迭代器）会在网络错误、`429` 和 `5xx` 时自动重试，连同首次最多 3 次，间隔指数递增；其他方法不自动重试，由你按排错页的建议处理。
- Python 默认超时 30 秒，可用 `Client(timeout=...)` 调整；Go 用调用时传入的 `context` 控制超时和取消。

## 接下来

- [关键词与语义检索](/docs/search)：平台、时间、语言和字段过滤。
- [用户、话题、标签与分类](/docs/browse)：精确筛选、分类 code 与字段权限。
- [读取内容与历史](/docs/documents)：正文、版本、片段和事实。
- [增量同步数据](/docs/change-feed)：处理整页后保存游标。
- [限流、重试与排错](/docs/production)：超时、限流和错误处理。

附件下载及 SDK 未封装的接口使用相同 Consumer Key，通过 HTTP API 调用。

## 继续当前任务

[返回接入路线](/docs)；查完所需信息后，回到正在执行的步骤。 