BharatStock Python Client
Official Python client for the BharatStock API — reliable Indian stock market data (NSE/BSE): EOD prices, quarterly/annual financials, shareholding patterns, corporate actions, derived per-stock metrics, a screener, bulk/block deals, insider trades, indices, and market-wide FII/DII activity.
Install
Once published:
pip install bharatstock
To use it locally from this repo before it's on PyPI (editable install):
pip install -e sdk/python
Requires Python 3.9+ and httpx.
Authentication
Every data endpoint is authenticated with your bsk_live_... key, sent in the
X-API-Key header. Get one from the dashboard.
from bharatstock import BharatStock
# Pass the key explicitly...
client = BharatStock(api_key="bsk_live_...")
# ...or set BHARATSTOCK_API_KEY in the environment and omit it:
client = BharatStock()
Quickstart
from bharatstock import BharatStock
client = BharatStock(api_key="bsk_live_...")
# A single stock, with latest price + ~70 derived metrics
stock = client.stocks.get("RELIANCE")
print(stock.company_name, stock.exchange)
print("P/E:", stock.metrics.pe_ratio, "ROE:", stock.metrics.roe)
# Batch quotes for a watchlist (one call, up to 50 symbols)
for q in client.stocks.quotes(["TCS", "INFY", "HDFCBANK"]):
print(q.symbol, q.close, q.change_pct)
# Search
for hit in client.search("tata"):
print(hit.symbol, hit.company_name)
# Public data-integrity status (no key required)
print(client.status().status) # "operational" | "degraded"
Pagination
List endpoints return a Page object: iterate it directly for the rows, or read
.total_pages / .has_next to page through manually.
# One page
page = client.stocks.prices("RELIANCE", from_date="2026-01-01", page_size=100)
print(page.total_items, page.total_pages)
for row in page:
print(row.trade_date, row.close, row.adjusted_close)
# Auto-iterate every stock across all pages (lazy generator)
for s in client.stocks.iter_all(sector="Banking"):
print(s.symbol)
Date ranges use from_date= / to_date= (sent to the API as from / to),
in YYYY-MM-DD form.
Screener
results = client.screener.run(
filters=["pe_ratio.lt.15", "roe.gt.18", "market_cap.gt.10000"], # Cr
sort_by="roe",
sort_order="desc",
page_size=25,
)
for r in results:
print(r.symbol, r.pe_ratio, r.roe)
Filter syntax is metric.operator.value where the operator is one of
gt | lt | gte | lte | eq. market_cap values are in Crores.
Rate limits & retries
Plans have a daily request cap. When you exceed it the API returns HTTP 429.
The client automatically retries a 429 a few times with exponential backoff
(the API does not send a Retry-After header, so the wait is client-side); if
it's still capped it raises RateLimitError.
from bharatstock import BharatStock, RateLimitError, NotFoundError
client = BharatStock(api_key="bsk_live_...", max_retries=3)
try:
stock = client.stocks.get("NONEXISTENT")
except NotFoundError:
print("no such ticker")
except RateLimitError as e:
print("slow down:", e.detail)
All errors subclass BharatStockError, so you can catch that one type to handle
any API failure. Specific subclasses: AuthenticationError (401),
NotFoundError (404), RateLimitError (429), BadRequestError (400/422),
APIError (everything else).
Resource map
| Group | Methods |
|---|---|
client.stocks |
list, iter_all, get, quotes, compare, prices, financials, ratios, corporate_actions, technical_indicators, shareholding, mf_holdings, bulk_deals, block_deals, insider_trades |
client.deals |
bulk, block, insider_trades (market-wide) |
client.screener |
run |
client.indices |
list, prices |
client.market |
fii_dii |
| top-level | search, movers, price_shockers, status |
Notes
market_capunits differ by endpoint (this mirrors the current API, so the client reports exactly what the server sends):- Rupees:
stocks.get,stocks.list/iter_all,search(StockSummary/StockDetail.market_cap),stocks.compare(ComparisonItem), andstocks.ratios(RatioSnapshot). - Crores (1 Cr = 10,000,000): the metrics block on
stocks.get(StockDetail.metrics.market_cap) andscreener.run(ScreenerResult). - The
screener.runmarket_capfilter value is also in Crores (e.g."market_cap.gt.10000"= > 10,000 Cr). Sostock.market_capandstock.metrics.market_capon the same object are in different units (rupees vs Crores) — divide the rupee value by 1e7 to compare. Convert withcrores = rupees / 10_000_000.
- Rupees:
- Use the client as a context manager (
with BharatStock(...) as c:) to close the underlying HTTP connection pool when you're done. - Types ship with the package (
py.typed), so editors autocomplete every method and response field.
License
MIT
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bharatstock-0.1.0.tar.gz.
File metadata
- Download URL: bharatstock-0.1.0.tar.gz
- Upload date:
- Size: 19.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7f448ea2915271626380122eb4ddd40f0951811b8f7b947123b1a203cc06c749
|
|
| MD5 |
c83b616059d04339715b8fb710ed9edb
|
|
| BLAKE2b-256 |
9a4c99a5c019b93214f53de5d82724436d6161d25aa9b41690599e537c3bdcbe
|
File details
Details for the file bharatstock-0.1.0-py3-none-any.whl.
File metadata
- Download URL: bharatstock-0.1.0-py3-none-any.whl
- Upload date:
- Size: 16.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a48b304fb178f94972405d309f211d8489a0f93ff2dd9d3799965187fcfc8449
|
|
| MD5 |
898f791bee5d242af7bacd83195c71ca
|
|
| BLAKE2b-256 |
c01fd1ff6f24188825802541c23cc0f67989d2647aedbdc393bbe942f245a3ca
|