DataBull Python SDK

One pip command to bring A-share, Hong Kong and US quotes and financials — plus ETFs, indices, SW sectors and news — into your Python project. Covers 42 REST endpoints and 38 MCP tools.

Current version v0.1.5

1 Install

Install from PyPI. The only core dependency is requests; add pandas when you need the *_history methods to return DataFrames.

Terminal
pip install databull pip install "databull[pandas]" # when you need DataFrames

If PyPI is slow from mainland China, or you are on an intranet, install the latest wheel hosted on this site directly:

Terminal
pip install https://www.databull.cn/sdk/files/databull-0.1.5-py3-none-any.whl

Or skip the package entirely and download a single file (all 28 methods, requests only):

Terminal
curl -fsSLO https://www.databull.cn/sdk/files/databull_client.py

Create your API Key for free in the console; free tier is 500 calls/day.

2 Quick start

Python
from databull import DataBull, DataBullError client = DataBull("dbt_xxxxxxxx") # or just set DATABULL_API_KEY env var # Stock daily history (returns a date-indexed DataFrame) df = client.get_stock_history("600519", "2026-01-01", "2026-09-01") # Index search and constituent weights hits = client.search_index("CSI 300", limit=5) cons = client.get_index_constituents("000300", page_size=10)["data"] # SW tier-1 sector change (sw1 / sw2 / sw3) sectors = client.get_sector_data("sw1")

You can also probe endpoints from the CLI, no code needed:

Terminal
python -m databull cn/index/search --params '{"keyword": "CSI 300"}'

3 Capabilities

All methods below are verified working against the live DataBull API.

Capability Method Path
Index daily history get_index_history GET /cn/index/history
Index list (paginated + filtered) get_index_list GET /cn/index/list
Index search (relevance ranked) search_index GET /cn/index/search
Index constituents & weights get_index_constituents GET /cn/index/constituents
A-share / ETF / index universe get_stock_list GET /cn/stocks
Stock basics get_stock_info GET /cn/stock/info
Company profile get_company_profile GET /cn/stock/profile
Stock historical quotes get_stock_history GET /cn/stock/history
Stock financial statements get_stock_financial_data GET /cn/stock/financial_data
US stock info / history get_us_stock_info / history GET /us/stock/*
HK stock info / history get_hk_stock_info / history GET /hk/stock/*
ETF list / basics get_etf_list / get_etf_info GET /cn/etfs/
ETF creation/redemption list (PCF) get_etf_pcf GET /cn/etfs/etf_pcf
ETF constituents get_etf_composition GET /cn/etfs/etf_composition
ETF NAV / history get_etf_history GET /cn/etf/history
News flash / source list get_news_flash / _sources GET /v2/news/flash
Market news list / detail get_market_news / _detail GET /cn/market/news
Fear & Greed Index get_fear_greed GET /cn/market/fear_greed
SW sector change get_sector_data GET /cn/market/sector_data/{sw1,sw2,sw3}
SW sector catalog get_sector_catalog GET /cn/market/sector_catalog/{sw1,sw2,sw3}
Stock realtime tick get_realtime GET /cn/stock/tick
Trading calendar get_trading_calendar GET /cn/tick/trading_calendar
MCP tool call call_mcp_tool POST /mcp/call

Full fields and examples in the API docs; MCP exposes get_stock_list / get_stock_detail / get_stock_history / get_index_history / get_financial_data as five tools.

4 Three conventions

No silent failures

Every failure raises DataBullError with the HTTP status and raw response body. 401 = invalid key, 403 = plan quota exceeded, 429 = rate limited. Never use "returns None" to check for failure — that mistakes a failed request for "this instrument has no data".

Empty results carry a reason

When there is no data the endpoint returns an empty array/object instead of erroring, and the reason is exposed on client.last_empty_reason: 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.

Always use bare codes

600519, not 600519.SH — the market is decided by the endpoint. Suffixing makes stocks 400, and makes indices silently return an empty array with no error. The SDK strips suffixes automatically. Also note market has two meanings: the base prefix is cn/us/hk, while the index-list filter is SSE/SZSE/CSI/SW (named index_market in the SDK; passing the wrong one is caught early).

5 Migrate from the old client

Old method names are kept as aliases, so existing code keeps working: 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. But the error semantics changed: the old version "logged and returned None", now it raises DataBullError — code that relied on the None branch must switch to except DataBullError.