Skip to main content

dalal

PyPI version Python 3.11+ License: MIT Tests

Unified Python API for Indian stock exchanges (NSE + BSE).

No API keys. No third-party exchange wrappers. Just requests under the hood.

Install

pip install dalal

Quick Start

import dalal

dalal.quote("RELIANCE")                          # NSE (default)
dalal.quote("500325", exchange="BSE")            # BSE
dalal.fundamentals("500325")                     # 3-period financials
dalal.actions("RELIANCE")                        # dividends, splits, bonuses
dalal.history("RELIANCE", "2025-01-01", "2025-12-31")

Need explicit session control? Use the Dalal class directly with a context manager.

Features

Method NSE BSE Default Description
quote() Yes Yes NSE Live price, OHLC, 52-week range
history() Yes - NSE Historical OHLCV (auto-chunks 100-day windows)
actions() Yes Yes NSE Corporate actions — dividends, splits, bonuses
fundamentals() - Yes BSE 3-period results — Revenue, PAT, EPS, OPM%, NPM%
meta() - Yes BSE PE, ROE, EPS, P/B ratios
index() Yes - NSE Index constituents with live prices
holidays() Yes - NSE Trading/clearing holidays
bulk_deals() Yes - NSE Historical bulk deal data
block_deals() Yes - NSE Intraday block deals
shareholding() Yes - NSE Promoter/public/FII holding pattern
gainers() Yes Yes NSE Top gainers by index
losers() Yes Yes NSE Top losers by index
announcements() Yes Yes NSE Corporate announcements
status() Yes Yes NSE Market open/closed status
lookup() Yes Yes NSE Symbol search / autocomplete
result_calendar() - Yes BSE Upcoming earnings dates
advances() Yes - NSE Advance/decline ratio

Usage

Quotes

import dalal

nse = dalal.quote("RELIANCE")
# {'symbol': 'RELIANCE', 'ltp': 1365.1, 'open': 1360.0, 'high': 1370.0,
#  'low': 1340.0, 'prev_close': 1350.0, 'year_high': 1600.0, ...}

bse = dalal.quote("500325", exchange="BSE")
# {'scripcode': '500325', 'ltp': 1365.1, 'open': 1340.0, ...}

Historical Data

import dalal

data = dalal.history("RELIANCE", "2025-01-01", "2025-06-30")
# [{'date': '2025-01-02', 'open': 1300.0, 'high': 1320.0,
#   'low': 1290.0, 'close': 1310.0, 'volume': 5000000.0}, ...]

# Works with pandas
import pandas as pd
df = pd.DataFrame(data)

Fundamentals (BSE)

import dalal

f = dalal.fundamentals("500325")
# {'scripcode': '500325', 'currency_unit': 'in Cr.',
#  'periods': [
#    {'period': 'Dec-25', 'revenue': 125741.0, 'net_profit': 9396.0,
#     'eps': 6.94, 'opm_pct': 14.56, 'npm_pct': 7.47},
#    {'period': 'Sep-25', ...},
#    {'period': 'FY24-25', ...}
#  ]}

m = dalal.meta("500325")
# {'eps': 35.21, 'pe': 38.77, 'roe': 9.09, 'pb': 3.52, ...}

Corporate Actions

import dalal

actions = dalal.actions("RELIANCE")
# [{'symbol': 'RELIANCE', 'subject': 'Dividend - Rs 5.5 Per Share',
#   'ex_date': '2025-08-14', ...},
#  {'symbol': 'RELIANCE', 'subject': 'Bonus 1:1',
#   'ex_date': '2024-10-28', ...}]

Index Constituents

import dalal

nifty = dalal.index("NIFTY 50")
# {'name': 'NIFTY 50', 'advance': 30, 'decline': 20,
#  'constituents': [
#    {'symbol': 'RELIANCE', 'ltp': 1365.0, 'pct_change': 1.12, ...},
#    ...
#  ]}

Error Handling

import dalal
from dalal import SymbolNotFound, RateLimited, NetworkError

try:
    dalal.quote("INVALID")
except SymbolNotFound:
    print("Symbol not found")
except RateLimited:
    print("Too many requests — slow down")
except NetworkError:
    print("Connection issue")

All exceptions inherit from DalalError:

DalalError
├── ExchangeError
│   ├── AuthError
│   ├── SymbolNotFound
│   └── DataNotAvailable
├── NetworkError
│   ├── RateLimited
│   └── ExchangeDown
└── ValidationError

Rate Limiting

Built-in rate limiting prevents IP bans:

  • NSE: 3 requests/second
  • BSE: 8 requests/second

Override if needed:

d = Dalal(nse_rate=2, bse_rate=5)

How It Works

dalal talks directly to the same APIs that nseindia.com and bseindia.com use internally. No API keys needed — it handles browser impersonation and cookie management automatically.

  • NSE: Cookie-primed session (auto-refreshes on 401)
  • BSE: Simple session with browser-like headers
  • Sessions are lazy: NSE session only created on first NSE call, same for BSE

Typing

dalal includes a py.typed marker for typed Python consumers.

Project Docs

Requirements

  • Python 3.11+
  • requests >= 2.31

License

MIT

Author

Aman (@onlyoneaman)

Metadata

Release files for dalal 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dalal 0.2.1
File Size Uploaded Provenance Actions
dalal-0.2.1.tar.gz 17.6 kB Without provenance Details for dalal-0.2.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for dalal 0.2.1
File Interpreter ABI Platform Actions
dalal-0.2.1-py3-none-any.whl Python 3 none any Details for dalal-0.2.1-py3-none-any.whl

Total release size: 32.0 kB

Release files / dalal-0.2.1.tar.gz

Download URL dalal-0.2.1.tar.gz
Size 17.6 kB
Tags Source
SHA-256 checksum
How to use checksums
b0b7e64f003fa994937e61680a42fe5e2a3d16ad4c65847e1b9707578f3529fb
BLAKE2b-256 checksum
How to use checksums
f2ce2541435cd1ea1a770dfd129dd84813d37e51ac6373b08f6558ae56a22732
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.14

Release files / dalal-0.2.1-py3-none-any.whl

Download URL dalal-0.2.1-py3-none-any.whl
Size 14.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a3c43042ab36eb0de6e21d7fe0424a515a0e8ef7cfa1baed33343af45247a789
BLAKE2b-256 checksum
How to use checksums
843cbfe33672893697ea5dfca0ffa17211c2a61627a657555e1a77024865efc6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.14

Security for dalal 0.2.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page