Metadata-Version: 2.4
Name: databull
Version: 0.1.0
Summary: DataBull 中国 A 股市场数据 API 官方 Python SDK（行情、财务、ETF、指数、板块、快讯）
Author-email: Yc <yccheni@163.com>
Project-URL: Homepage, https://www.databull.cn
Project-URL: Documentation, https://www.databull.cn/docs
Project-URL: Source, https://www.databull.cn/sdk
Project-URL: API Console, https://www.databull.cn/console
Keywords: databull,stock,a-share,china,finance,market-data,api,etf,index
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Office/Business :: Financial :: Investment
Classifier: Typing :: Typed
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: requests>=2.28
Requires-Dist: urllib3>=1.26
Provides-Extra: pandas
Requires-Dist: pandas>=1.5; extra == "pandas"

# databull — DataBull Python SDK

DataBull 中国 A 股市场数据 API 的官方 Python 客户端。覆盖**沪深个股日线与实时行情、财务报表、
ETF（含申赎清单与成分股）、指数清单/搜索/成分股权重、申万板块、市场情绪、财经快讯**，
共 28 个 REST 端点与 5 个 MCP 工具。

- 官网与文档：https://www.databull.cn/docs
- 免费注册并创建 API Key：https://www.databull.cn/console/register

## 安装

```bash
pip install databull              # 仅 JSON 查询，依赖只有 requests
pip install "databull[pandas]"    # 需要 *_history / fear_greed 返回 DataFrame 时
```

国内直连 PyPI 慢时，可从官网下载 wheel 安装：

```bash
pip install https://www.databull.cn/sdk/files/databull-0.1.0-py3-none-any.whl
```

## 快速开始

```python
from databull import DataBull, DataBullError

client = DataBull("dbt_xxxxxxxx")          # 也可只设环境变量 DATABULL_API_KEY
# 自建/代理时可指定基址：DataBull(api_key, base_url="https://api.example.com")

# 个股日线（返回带日期索引的 DataFrame）
df = client.get_stock_history("600519", "2026-01-01", "2026-09-01")
print(df.tail())

# 指数搜索与成分股权重
hits = client.search_index("沪深300", limit=5)
cons = client.get_index_constituents("000300", page_size=10)["data"]

# 申万一级行业涨跌
sectors = client.get_sector_data("sw1")
```

命令行也可以直接探接口（不用写代码）：

```bash
export DATABULL_API_KEY=dbt_xxxxxxxx
python -m databull cn/index/search --params '{"keyword": "沪深300"}'
databull cn/stocks --params '{"q": "茅台"}'      # 安装了就绪脚本
python -m databull --version
```

## 出错与空结果

**出错不静默**：所有失败都抛 `DataBullError`，带上 HTTP 状态码与原始响应体。
不要用「返回 None」判断失败——本项目历史上就吃过这个亏。

```python
try:
    client.get_stock_history("600519", "2026-01-01", "2026-09-01")
except DataBullError as e:
    print(e.status, e)          # 401=Key 无效 403=超出套餐额度 429=调用频率超限
    print(e.body)
```

**空结果带原因**：接口在「没有数据」时返回空数组/空对象而不是报错，原因通过响应头
`X-Empty-Reason`（数组型）或体内 `empty_reason`（对象型）给出，SDK 把它挂到
`client.last_empty_reason`：

```python
data = client.get_index_constituents("801010")
if not data["data"]["items"]:
    print(client.last_empty_reason)   # constituents_not_synced = 该指数不在每日同步名单
```

常见取值：`index_not_found`、`no_data_in_range`、`calendar_not_loaded`、`no_match`、
`sector_data_not_collected`、`tick_not_uploaded`、`catalog_not_synced`、
`constituents_not_synced`。

## 参数与返回约定（容易踩的两点）

1. **代码一律用裸码**，不带交易所后缀：`600519` 而不是 `600519.SH`；市场由接口决定。
   传后缀时个股会 400，指数**不报错但静默返回空数组**——SDK 已自动剥离后缀，
   但你自己拼 URL 时要注意。
2. **日期写法都收**：`2026-08-01`、`20260801`、`2026/8/1` 都可以。服务端并不统一——
   实测只有 `/cn/index/history` 严格要求 `YYYYMMDD`（传 `2026-08-01` 直接 400），
   其余端点两种都收；SDK 在发请求前统一转换，所以你不必记这件事。
3. **`market` 有两种含义**：作为基址路径前缀时是 `cn` / `us` / `hk`；作为**指数清单的
   过滤条件**时是 `SSE` / `SZSE` / `CSI` / `SW`。两者混用不会报错、只会筛不到。
   SDK 把后者命名为 `index_market` 并会提前拦下错误取值。

**返回形态不统一**：多数方法返回 `{"code": 0, "data": ...}`，但少数接口直接返回数组
（例如 `get_sector_data` 返回 `[{...}, ...]`）。SDK 原样透传，不做包装——
按方法逐个确认一次，比被一层"透明"包装误导更好。

## 端点与方法对照

| 能力 | 方法 | 路径 |
| --- | --- | --- |
| 指数历史日线 | `get_index_history` | `GET /cn/index/history` |
| 指数清单（分页/过滤） | `get_index_list` | `GET /cn/index/list` |
| 指数搜索（相关度排序） | `search_index` | `GET /cn/index/search` |
| 指数成分股与权重 | `get_index_constituents` | `GET /cn/index/constituents` |
| A股/ETF/指数标的清单 | `get_stock_list` | `GET /cn/stocks` |
| 个股基本信息 | `get_stock_info` | `GET /cn/stock/info` |
| 公司简介 | `get_company_profile` | `GET /cn/stock/profile` |
| 个股历史行情 | `get_stock_history` | `GET /cn/stock/history` |
| 个股财务报表 | `get_stock_financial_data` | `GET /cn/stock/financial_data` |
| 美股基本信息 / 历史 | `get_us_stock_info` / `get_us_stock_history` | `GET /us/stock/info`, `/us/stock/history` |
| 港股基本信息 / 历史 | `get_hk_stock_info` / `get_hk_stock_history` | `GET /hk/stock/info`, `/hk/stock/history` |
| ETF 清单 | `get_etf_list` | `GET /cn/etfs/` |
| ETF 基本信息 | `get_etf_info` | `GET /cn/etfs/info` |
| ETF 申赎清单（PCF） | `get_etf_pcf` | `GET /cn/etfs/etf_pcf` |
| ETF 成分股 | `get_etf_composition` | `GET /cn/etfs/etf_composition` |
| ETF 历史净值/行情 | `get_etf_history` | `GET /cn/etf/history` |
| 财经快讯 | `get_news_flash` | `GET /v2/news/flash` |
| 快讯来源列表 | `get_news_flash_sources` | `GET /v2/news/flash/sources` |
| 市场新闻列表 / 详情 | `get_market_news` / `get_market_news_detail` | `GET /cn/market/news`, `/cn/market/news/{id}` |
| 恐惧与贪婪指数 | `get_fear_greed` | `GET /cn/market/fear_greed` |
| 申万板块涨跌幅 | `get_sector_data` | `GET /cn/market/sector_data/{sw1,sw2,sw3}` |
| 申万行业清单 | `get_sector_catalog` | `GET /cn/market/sector_catalog/{sw1,sw2,sw3}` |
| 个股实时 Tick | `get_realtime` | `GET /cn/stock/tick` |
| 全量 Tick 快照 | `get_tick_all` | `GET /cn/tick/tickall` |
| 交易日历 | `get_trading_calendar` | `GET /cn/tick/trading_calendar` |
| MCP 工具调用 | `call_mcp_tool` | `POST /mcp/call` |

MCP 已暴露的工具：`get_stock_list`、`get_stock_detail`、`get_stock_history`、
`get_index_history`、`get_financial_data`。

### 旧方法名（已废弃，仍可用）

从仓库内旧客户端迁移过来的方法名保留为别名，方便存量代码不改：
`get_history` → `get_stock_history`、`get_market_sector` → `get_sector_data`、
`get_company` → `get_company_profile`、`get_last_tick` → `get_realtime`、
`get_market_fear_greed` → `get_fear_greed`。
注意**出错语义已变**：旧版是「打印后返回 None」，现在是抛 `DataBullError`。

## 版本

版本号唯一源是 `databull/client.py` 的 `__version__`：

```python
import databull
print(databull.__version__)
```

## 版权

Copyright (c) 2025 yccheni@163.com. All rights reserved.
