Skip to main content

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

Project description

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)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dalal-0.2.0.tar.gz (17.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dalal-0.2.0-py3-none-any.whl (14.2 kB view details)

Uploaded Python 3

File details

Details for the file dalal-0.2.0.tar.gz.

File metadata

  • Download URL: dalal-0.2.0.tar.gz
  • Upload date:
  • Size: 17.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for dalal-0.2.0.tar.gz
Algorithm Hash digest
SHA256 c7aa8cb56da44f36e23f1013042077e0b665743060d3011553af7b1ec38e1d31
MD5 fce82b425eb746b2d53f006c00f29781
BLAKE2b-256 40428c76f05967ce134b61b204e1c2c99a2520e31b868b26e8c72daef55c0e1c

See more details on using hashes here.

File details

Details for the file dalal-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: dalal-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 14.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for dalal-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0072eb9b05b70ae77cc8e67f93db89c20b8dd9cc9e8fdfa5a17f8c8bda742d2e
MD5 f01b00e1de7c918020164e115aa46d88
BLAKE2b-256 c31ff1ba04b88c4886acc1e4dffee55976660139441a2b0834fd7073a22de4a5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page