Skip to content
 
 

Repository files navigation

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
Loading
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.

About

No description, website, or topics provided.

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages