Skip to main content

Production-grade NSE data engine for Python. Cache-first, circuit-protected, async-ready.

Project description

nsefetch

Production-grade NSE data engine for Python. Cache-first, circuit-protected, async-ready.

CI PyPI version Python License: MIT

pip install nsefetch

Quick Start

from nsefetch import MarketService

with MarketService() as service:
    quote = service.get_stock("RELIANCE")
    print(quote.data.last_price)         # e.g. 2947.35

    chain = service.get_option_chain("NIFTY")
    print(chain.data.expiry)             # nearest expiry date

Features

  • Cache-first runtime — in-process or Redis-backed, with per-operation TTLs
  • 🔌 Circuit breaker — automatic failure isolation and recovery
  • 🔄 Request coalescing — deduplicates concurrent identical requests within a process
  • 🚦 GCRA rate limiter — Redis or in-memory, prevents NSE from rate-limiting you
  • 🌊 Stale fallback — serves cached data gracefully on live fetch failure
  • ⚙️ Async parity — every sync method has an exact async equivalent
  • 🛡️ Typed responses — Pydantic v2 models on every response, always a ResponseEnvelope[T]
  • 🧪 131 tests — zero live-network calls in normal test runs
  • 🔒 NSE-only — no silent Yahoo Finance substitution; you always know what you're getting

API Reference

All methods are available on both MarketService (sync) and AsyncMarketService (async).

Method Description
get_nifty50() NIFTY 50 index snapshot
get_index(index_name) Any supported NSE index snapshot
get_stock(symbol) Single-symbol equity quote
get_bulk_stocks(symbols) Multi-symbol equity quotes with smart batching
get_option_chain(symbol, expiry=None) Option chain; defaults to nearest expiry
get_option_chain_expiries(symbol) All available option expiry dates
get_futures_data(symbol) F&O futures snapshot
get_delivery_data(symbol) Delivery / DPIIT data
get_market_depth(symbol) Level-2 order book (optional data)
get_sector_data() All NSE sector snapshots

Every method returns ResponseEnvelope[T] with:

envelope.success        # bool
envelope.data           # typed payload
envelope.cache_hit      # bool — was this served from cache?
envelope.stale          # bool — was this a stale cache fallback?
envelope.degraded       # bool — did a backend component fail?
envelope.fetched_at     # datetime
envelope.warnings       # list of WarningInfo

Runtime Modes

Direct (default)

Simple. No Redis, no background infrastructure needed.

from nsefetch import MarketService

service = MarketService()
quote = service.get_stock("RELIANCE")
service.close()

# or use as a context manager
with MarketService() as service:
    quote = service.get_stock("RELIANCE")

Cached (scripts & repeated polling)

Adds in-process LRU cache + rate limiter. Best for local scripts that poll repeatedly.

from nsefetch import create_cached_market_service

with create_cached_market_service() as service:
    # First call hits NSE; subsequent calls within TTL hit cache
    quote = service.get_stock("RELIANCE")

Production (Redis-backed)

For dashboard backends and multi-worker deployments. Keeps frontend traffic reading from cache instead of hammering NSE directly.

from nsefetch import create_production_market_service

with create_production_market_service() as service:
    snapshot = service.get_nifty50()

Async

All three modes have async counterparts:

from nsefetch import AsyncMarketService, create_async_cached_market_service

async with AsyncMarketService() as service:
    quote = await service.get_stock("INFY")

async with create_async_cached_market_service() as service:
    chain = await service.get_option_chain("BANKNIFTY")

Option Chain with Specific Expiry

with MarketService() as service:
    # Discover all available expiries
    expiries = service.get_option_chain_expiries("NIFTY")
    print(expiries.data)   # ['2026-05-29', '2026-06-26', ...]

    # Fetch a specific expiry
    chain = service.get_option_chain("NIFTY", expiry="2026-06-26")

Architecture

graph TD
    A[MarketService / AsyncMarketService] --> B[Rate Limiter]
    B --> C[Cache Layer]
    C -->|cache miss| D[Circuit Breaker]
    D --> E[NSE HTTP Client]
    E --> F[curl_cffi Transport]
    F --> G[NSE API]
    C -->|cache hit| H[ResponseEnvelope]
    D -->|open| I[Stale Fallback Cache]
    I --> H
Layer Component Purpose
Service MarketService Public API, context manager lifecycle
Reliability CircuitBreaker Blocks requests when provider is failing
Reliability RateLimiter GCRA — prevents NSE from blocking you
Caching CacheManager In-memory or Redis, request coalescing
Transport NSEHttpClient Browser-impersonating session (curl_cffi)
Normalizer NSEMarketDataNormalizer Raw payload → typed Pydantic schemas

Configuration

All settings are configurable via environment variables prefixed with NSEFETCH_:

# Redis connection (for production/cached modes)
NSEFETCH_REDIS_URL=redis://localhost:6379/0

# Cache TTLs (seconds)
NSEFETCH_CACHE_TTL_STOCK=15
NSEFETCH_CACHE_TTL_INDEX=10
NSEFETCH_CACHE_TTL_OPTION_CHAIN=30

# Circuit breaker
NSEFETCH_CIRCUIT_BREAKER_FAILURE_THRESHOLD=5
NSEFETCH_CIRCUIT_BREAKER_RECOVERY_WINDOW=60

# Rate limiter
NSEFETCH_RATE_LIMIT_REQUESTS_PER_SECOND=2

# Live probe gate
NSEFETCH_LIVE_PROBE_ENABLED=1

Or pass a Settings object directly:

from nsefetch import MarketService, Settings

settings = Settings(redis_url="redis://localhost:6379/0")
service = MarketService(settings=settings)

Live Probe

Test your connectivity to NSE before deploying:

# Transport-level probe
NSEFETCH_LIVE_PROBE_ENABLED=1 python -m nsefetch.live_probe

# Service-level probe (exercises all 10 methods)
NSEFETCH_LIVE_PROBE_ENABLED=1 python -m nsefetch.live_probe --service

# Both together
NSEFETCH_LIVE_PROBE_ENABLED=1 python -m nsefetch.live_probe --all

Contributing

Contributions are welcome! See CONTRIBUTING.md for setup instructions, coding standards, and PR guidelines.

Good first issues include: new index names, BSE provider, pandas integration, and export utilities.


Legal

This library is for educational and research purposes only. It is not affiliated with, endorsed by, or connected to the National Stock Exchange of India (NSE). Use at your own risk.

See DISCLAIMER.md for the full legal notice and LICENSE for the MIT license.

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

nsefetch-0.1.0.tar.gz (54.8 kB view details)

Uploaded Source

Built Distribution

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

nsefetch-0.1.0-py3-none-any.whl (42.8 kB view details)

Uploaded Python 3

File details

Details for the file nsefetch-0.1.0.tar.gz.

File metadata

  • Download URL: nsefetch-0.1.0.tar.gz
  • Upload date:
  • Size: 54.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for nsefetch-0.1.0.tar.gz
Algorithm Hash digest
SHA256 2d4218b23c25d856b7cb839141de52f6ba86bf688d0ee9074d1696dc3ad5a7a2
MD5 37dad51ba5ce20d34a1d130acee2fb10
BLAKE2b-256 6d33a4d71c0b4600ef7aa428df8d52c8f12def76535d29e0ed7f8c9872327d4b

See more details on using hashes here.

Provenance

The following attestation bundles were made for nsefetch-0.1.0.tar.gz:

Publisher: publish.yml on harsh-kumar-rai/nsefetch

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file nsefetch-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: nsefetch-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 42.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for nsefetch-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f11563817c426cc929b3e0a3535260e6d860a2bc7a7aa18afa9db5c4600275fd
MD5 e4567a3b7d16d59d0527a3f77a6c4d1f
BLAKE2b-256 41b8b7002f7b0dcf3ea52905ae996ee01b9cdb63d4a9835a1d5de492a0570491

See more details on using hashes here.

Provenance

The following attestation bundles were made for nsefetch-0.1.0-py3-none-any.whl:

Publisher: publish.yml on harsh-kumar-rai/nsefetch

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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