A Python package for fetching historical data from Zerodha API Using Account Credentials.
Project description
Zerodha Data Fetcher
A Python package for fetching historical data from Zerodha API with advanced features like rate limiting, authentication management, parallel data fetching, and multi-account support for massive data retrieval.
Features
- 🚀 Fast Parallel Data Fetching: Concurrent requests with intelligent rate limiting
- 🔐 Automatic Authentication: Handles login, 2FA, and token management
- 📊 Multiple Data Formats: Support for minute, daily, and other timeframes
- 🛡️ Error Handling: Robust error handling with retry mechanisms
- 🔍 Symbol Search: Built-in instrument search and validation
- ⚙️ Configurable: Flexible configuration via environment variables or parameters
- 🏭 Multi-Account Support: Create multiple instances for massive parallel data retrieval
- 🔧 Runtime Configuration Override: Override environment variables at runtime
Installation
pip install zerodha-data-fetcher
Quick Start
1. Set up TOTP (Time-based OTP)
First, you need to set up TOTP for your Zerodha account. Follow this tutorial: Zerodha TOTP Setup Guide
2. Set up environment variables
Create a .env file in your project root:
# Required credentials
ZERODHA_USER_ID=your_user_id
ZERODHA_PASSWORD=your_password
ZERODHA_TOTP_SECRET=your_totp_secret
# Optional configurations
ZERODHA_TYPE=user_id
ZERODHA_BASE_URL=https://kite.zerodha.com
ZERODHA_LOGIN_URL=https://kite.zerodha.com/api/login
ZERODHA_2FA_URL=https://kite.zerodha.com/api/twofa
ZERODHA_HISTORICAL_URL=https://kite.zerodha.com/oms/instruments/historical/{token}/{timeframe}?user_id={userid}&oi=1&from={current_date}&to={next_date}
ZERODHA_KEYRING_TOKEN_KEY=zerodha_auth_token
ZERODHA_KEYRING_ENCRYPTION_KEY=zerodha_encryption_key
3. Basic Usage
from zerodha_data_fetcher import ZerodhaDataFetcher, setup_logging
from datetime import date, timedelta
# Setup logging (optional)
setup_logging(log_level="INFO", log_file="logs/zerodha_fetcher.log")
# Initialize the fetcher
fetcher = ZerodhaDataFetcher(requests_per_second=3)
# Define date range
end_date = date.today()
start_date = end_date - timedelta(days=30)
# Example 1: Fetch data using instrument token
data = fetcher.fetch_historical_data(
ticker_token=408065, # HDFC Bank instrument token
start_date=start_date,
end_date=end_date,
timeframe="minute"
)
print(f"Retrieved {len(data)} records")
print(data.head())
# Example 2: Fetch data using symbol name
data = fetcher.fetch_historical_data(
ticker_token="RELIANCE",
start_date=start_date,
end_date=end_date,
timeframe="minute"
)
print(f"Retrieved {len(data)} records for RELIANCE")
print(data.head())
# Example 3: Search for symbols
search_results = fetcher.search_symbols("TATA", limit=5)
print("Found symbols:", search_results[['Instrument_Token', 'Name', 'Exchange']])
# Example 4: Get instrument information
instrument_info = fetcher.get_instrument_info("INFY")
print("Instrument info:", instrument_info)
4. Runtime Configuration Override
You can override environment variables during class instantiation:
# Override credentials at runtime (useful when env vars become obsolete)
fetcher = ZerodhaDataFetcher(
requests_per_second=3,
user_id="override_user_id",
password="override_password",
totp_secret="override_totp_secret",
user_type="user_id" # or "corporate"
)
Multi-Account Parallel Processing
For massive data retrieval, you can create multiple instances with different credentials to bypass individual account rate limits:
import asyncio
from concurrent.futures import ThreadPoolExecutor
from datetime import date, timedelta
# Account configurations
accounts = [
{
"user_id": "account1_id",
"password": "account1_password",
"totp_secret": "account1_totp_secret"
},
{
"user_id": "account2_id",
"password": "account2_password",
"totp_secret": "account2_totp_secret"
},
{
"user_id": "account3_id",
"password": "account3_password",
"totp_secret": "account3_totp_secret"
}
]
def fetch_data_with_account(account_config, symbols_batch):
"""Fetch data using a specific account for a batch of symbols."""
fetcher = ZerodhaDataFetcher(
requests_per_second=3,
user_id=account_config["user_id"],
password=account_config["password"],
totp_secret=account_config["totp_secret"]
)
results = {}
end_date = date.today()
start_date = end_date - timedelta(days=30)
for symbol in symbols_batch:
try:
data = fetcher.fetch_historical_data(
ticker_token=symbol,
start_date=start_date,
end_date=end_date,
timeframe="minute"
)
results[symbol] = data
print(f"✅ Account {account_config['user_id']}: Fetched {len(data)} records for {symbol}")
except Exception as e:
print(f"❌ Account {account_config['user_id']}: Failed to fetch {symbol}: {e}")
results[symbol] = None
return results
# Symbols to fetch (split into batches for each account)
all_symbols = ["RELIANCE", "HDFC", "INFY", "TCS", "ICICIBANK", "SBIN", "BAJFINANCE", "BHARTIARTL", "HDFCBANK"]
# Split symbols across accounts
symbols_per_account = len(all_symbols) // len(accounts)
symbol_batches = [
all_symbols[i:i + symbols_per_account]
for i in range(0, len(all_symbols), symbols_per_account)
]
# Ensure any remaining symbols are included
if len(symbol_batches) > len(accounts):
symbol_batches[-2].extend(symbol_batches[-1])
symbol_batches.pop()
# Execute parallel fetching
with ThreadPoolExecutor(max_workers=len(accounts)) as executor:
futures = []
for i, account in enumerate(accounts):
if i < len(symbol_batches):
future = executor.submit(fetch_data_with_account, account, symbol_batches[i])
futures.append(future)
# Collect results
all_results = {}
for future in futures:
batch_results = future.result()
all_results.update(batch_results)
print(f"\n🎉 Completed fetching data for {len(all_results)} symbols across {len(accounts)} accounts")
Configuration
Environment Variables
| Variable | Description | Required | Default |
|---|---|---|---|
ZERODHA_USER_ID |
Your Zerodha user ID | Yes | - |
ZERODHA_PASSWORD |
Your Zerodha password | Yes | - |
ZERODHA_TOTP_SECRET |
TOTP secret for 2FA (Setup Guide) | Yes | - |
ZERODHA_TYPE |
Account type (user_id/corporate) | No | user_id |
ZERODHA_BASE_URL |
Zerodha base URL | No | https://kite.zerodha.com |
ZERODHA_LOGIN_URL |
Login endpoint URL | No | https://kite.zerodha.com/api/login |
ZERODHA_2FA_URL |
2FA endpoint URL | No | https://kite.zerodha.com/api/twofa |
ZERODHA_HISTORICAL_URL |
Historical data endpoint template | No | [Default template] |
ZERODHA_KEYRING_TOKEN_KEY |
Keyring token storage key | No | zerodha_auth_token |
ZERODHA_KEYRING_ENCRYPTION_KEY |
Keyring encryption key | No | zerodha_encryption_key |
Note: Only ZERODHA_USER_ID, ZERODHA_PASSWORD, and ZERODHA_TOTP_SECRET are required to work. All other variables have sensible defaults and can be overridden during class instantiation if needed.
Class Parameters
requests_per_second: API rate limit (1-10, default: 2)token_expiry_hours: Token validity period (default: 6)user_id: Override environment variablepassword: Override environment variabletotp_secret: Override environment variableuser_type: Override environment variabletimeframe: Data timeframe ('minute', 'day', etc.)
Sample Output
When you run the basic usage example, you'll see output similar to:
🚀 Zerodha Data Fetcher - Basic Usage Example
==================================================
📊 Example 1: Fetching data using instrument token
----------------------------------------
Fetching data for token 408065 from 2025-08-07 to 2025-09-06
✅ Success! Retrieved 7500 records
📅 Date range: 2025-08-07 to 2025-09-05
🕐 Time range: 09:15 to 15:29
📋 Sample data:
Date Time Open High Low Close Volume
0 2025-08-07 09:15 1430.0 1434.8 1429.0 1434.1 67617
1 2025-08-07 09:16 1433.3 1434.5 1432.0 1433.3 12890
2 2025-08-07 09:17 1433.4 1433.5 1432.5 1433.0 15283
3 2025-08-07 09:18 1433.5 1433.6 1430.7 1430.7 23382
4 2025-08-07 09:19 1430.9 1431.3 1430.0 1431.0 16791
📊 Example 2: Fetching data using symbol
----------------------------------------
✅ Success! Retrieved 7500 records for RELIANCE
🔍 Example 3: Searching for symbols
----------------------------------------
✅ Found 5 matching symbols:
Instrument_Token Name Exchange
9472 128102404 TATAPOWER BSE
9478 128104452 TATAELXSI BSE
📋 Example 4: Getting instrument information
----------------------------------------
✅ Instrument information:
Instrument_Token: 128053508
Name: INFY
FullName: INFOSYS
API Reference
ZerodhaDataFetcher
Main class for fetching historical data.
Methods
fetch_historical_data(ticker_token, start_date, end_date, timeframe='minute'): Fetch historical datasearch_symbols(partial_name, limit=10): Search for trading symbolsget_instrument_info(symbol): Get instrument information
Error Handling
The package includes comprehensive error handling:
from zerodha_data_fetcher.utils.exceptions import (
ZerodhaAPIError,
AuthenticationError,
InvalidTickerError,
DataFetchError
)
try:
data = fetcher.fetch_historical_data("INVALID", start_date, end_date)
except InvalidTickerError as e:
print(f"Invalid ticker: {e}")
except AuthenticationError as e:
print(f"Auth failed: {e}")
except DataFetchError as e:
print(f"Data fetch failed: {e}")
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Disclaimer
This package is for educational and research purposes. Please ensure compliance with Zerodha's terms of service and applicable regulations when using this package.
Support
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
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 zerodha_data_fetcher-1.0.1.tar.gz.
File metadata
- Download URL: zerodha_data_fetcher-1.0.1.tar.gz
- Upload date:
- Size: 1.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2e141c74954c4952e4430bbdb60abbbeafacc19d5cb2cfe4641f0817231735e3
|
|
| MD5 |
a48e68e65a825e3d5e510592d6e3b54d
|
|
| BLAKE2b-256 |
12284d9e9129335619ebbed2fa6ee7b803b085d419f3ce0a93db37b65befa6f7
|
File details
Details for the file zerodha_data_fetcher-1.0.1-py3-none-any.whl.
File metadata
- Download URL: zerodha_data_fetcher-1.0.1-py3-none-any.whl
- Upload date:
- Size: 1.2 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9de1ad353cf4dd43a6d7882e070b1f43456ef7708fd0748c6efc8577a1a7aef7
|
|
| MD5 |
b8fdfe77a584d678175fe6873a59b8f4
|
|
| BLAKE2b-256 |
10507bfd513380950bb6e29ba9f18db09a7b18198fb96271f3f0a65ba5438009
|