zerodha-data-fetcher 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. zerodha_data_fetcher-1.0.0/LICENSE +0 -0
  2. zerodha_data_fetcher-1.0.0/MANIFEST.in +9 -0
  3. zerodha_data_fetcher-1.0.0/PKG-INFO +209 -0
  4. zerodha_data_fetcher-1.0.0/README.md +162 -0
  5. zerodha_data_fetcher-1.0.0/pyproject.toml +87 -0
  6. zerodha_data_fetcher-1.0.0/setup.cfg +4 -0
  7. zerodha_data_fetcher-1.0.0/setup.py +6 -0
  8. zerodha_data_fetcher-1.0.0/src/zerodha_data_fetcher/__init__.py +24 -0
  9. zerodha_data_fetcher-1.0.0/src/zerodha_data_fetcher/core/__init__.py +43 -0
  10. zerodha_data_fetcher-1.0.0/src/zerodha_data_fetcher/core/auth.py +101 -0
  11. zerodha_data_fetcher-1.0.0/src/zerodha_data_fetcher/core/data_fetcher.py +538 -0
  12. zerodha_data_fetcher-1.0.0/src/zerodha_data_fetcher/core/instrument_manager.py +283 -0
  13. zerodha_data_fetcher-1.0.0/src/zerodha_data_fetcher/core/rate_limiter.py +48 -0
  14. zerodha_data_fetcher-1.0.0/src/zerodha_data_fetcher/core/token_generator.py +204 -0
  15. zerodha_data_fetcher-1.0.0/src/zerodha_data_fetcher/utils/__init__.py +79 -0
  16. zerodha_data_fetcher-1.0.0/src/zerodha_data_fetcher/utils/config.py +163 -0
  17. zerodha_data_fetcher-1.0.0/src/zerodha_data_fetcher/utils/data/Kite_Instrument_ID.csv +86685 -0
  18. zerodha_data_fetcher-1.0.0/src/zerodha_data_fetcher/utils/data_loader.py +60 -0
  19. zerodha_data_fetcher-1.0.0/src/zerodha_data_fetcher/utils/encryption.py +86 -0
  20. zerodha_data_fetcher-1.0.0/src/zerodha_data_fetcher/utils/exceptions.py +31 -0
  21. zerodha_data_fetcher-1.0.0/src/zerodha_data_fetcher/utils/helpers.py +127 -0
  22. zerodha_data_fetcher-1.0.0/src/zerodha_data_fetcher/utils/logging_config.py +98 -0
  23. zerodha_data_fetcher-1.0.0/src/zerodha_data_fetcher.egg-info/PKG-INFO +209 -0
  24. zerodha_data_fetcher-1.0.0/src/zerodha_data_fetcher.egg-info/SOURCES.txt +25 -0
  25. zerodha_data_fetcher-1.0.0/src/zerodha_data_fetcher.egg-info/dependency_links.txt +1 -0
  26. zerodha_data_fetcher-1.0.0/src/zerodha_data_fetcher.egg-info/requires.txt +20 -0
  27. zerodha_data_fetcher-1.0.0/src/zerodha_data_fetcher.egg-info/top_level.txt +1 -0
Binary file
@@ -0,0 +1,9 @@
1
+ include README.md
2
+ include LICENSE
3
+ include pyproject.toml
4
+ include setup.py
5
+ recursive-include src/zerodha_data_fetcher *.py
6
+ recursive-include src/zerodha_data_fetcher/utils/data *.csv
7
+ recursive-include src/zerodha_data_fetcher/utils/data *.json
8
+ recursive-exclude * __pycache__
9
+ recursive-exclude * *.py[co]
@@ -0,0 +1,209 @@
1
+ Metadata-Version: 2.4
2
+ Name: zerodha-data-fetcher
3
+ Version: 1.0.0
4
+ Summary: A Python package for fetching historical data from Zerodha API
5
+ Author-email: Jayam Gupta <guptajayam47@gmail.com>
6
+ Maintainer-email: Jayam Gupta <guptajayam47@gmail.com>
7
+ License-Expression: MIT
8
+ Project-URL: Homepage, https://github.com/JayceeGupta/Zerodha-Data-Fetcher
9
+ Project-URL: Repository, https://github.com/JayceeGupta/Zerodha-Data-Fetcher
10
+ Project-URL: Documentation, https://github.com/JayceeGupta/Zerodha-Data-Fetcher#readme
11
+ Project-URL: Bug Tracker, https://github.com/JayceeGupta/Zerodha-Data-Fetcher/issues
12
+ Keywords: zerodha,trading,data,api,historical,stock-market
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Financial and Insurance Industry
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.8
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Topic :: Office/Business :: Financial
24
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
25
+ Requires-Python: >=3.8
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: requests>=2.25.0
29
+ Requires-Dist: pandas>=1.3.0
30
+ Requires-Dist: python-dateutil>=2.8.0
31
+ Requires-Dist: pyotp>=2.6.0
32
+ Requires-Dist: keyring>=23.0.0
33
+ Requires-Dist: cryptography>=3.4.0
34
+ Requires-Dist: Brotli>=1.0.9
35
+ Provides-Extra: dev
36
+ Requires-Dist: pytest>=6.0; extra == "dev"
37
+ Requires-Dist: pytest-cov>=2.0; extra == "dev"
38
+ Requires-Dist: black>=21.0; extra == "dev"
39
+ Requires-Dist: flake8>=3.9; extra == "dev"
40
+ Requires-Dist: mypy>=0.910; extra == "dev"
41
+ Requires-Dist: pre-commit>=2.15; extra == "dev"
42
+ Provides-Extra: docs
43
+ Requires-Dist: sphinx>=4.0; extra == "docs"
44
+ Requires-Dist: sphinx-rtd-theme>=1.0; extra == "docs"
45
+ Requires-Dist: myst-parser>=0.15; extra == "docs"
46
+ Dynamic: license-file
47
+
48
+ # Zerodha Data Fetcher
49
+
50
+ A Python package for fetching historical data from Zerodha API with advanced features like rate limiting, authentication management, and parallel data fetching.
51
+
52
+ ## Features
53
+
54
+ - 🚀 **Fast Parallel Data Fetching**: Concurrent requests with intelligent rate limiting
55
+ - 🔐 **Automatic Authentication**: Handles login, 2FA, and token management
56
+ - 📊 **Multiple Data Formats**: Support for minute, daily, and other timeframes
57
+ - 🛡️ **Error Handling**: Robust error handling with retry mechanisms
58
+ - 🔍 **Symbol Search**: Built-in instrument search and validation
59
+ - ⚙️ **Configurable**: Flexible configuration via environment variables or parameters
60
+
61
+ ## Installation
62
+
63
+ ```bash
64
+ pip install zerodha-data-fetcher
65
+ ```
66
+
67
+ ## Quick Start
68
+
69
+ ### 1. Set up environment variables
70
+
71
+ Create a `.env` file in your project root:
72
+
73
+ ```env
74
+ ZERODHA_USER_ID=your_user_id
75
+ ZERODHA_PASSWORD=your_password
76
+ ZERODHA_USER_TYPE=individual
77
+ ZERODHA_TOTP_SECRET=your_totp_secret
78
+ ```
79
+
80
+ ### 2. Basic Usage
81
+
82
+ ```python
83
+ from zerodha_data_fetcher import ZerodhaDataFetcher
84
+ from datetime import date, timedelta
85
+
86
+ # Initialize the fetcher
87
+ fetcher = ZerodhaDataFetcher(requests_per_second=2)
88
+
89
+ # Fetch historical data
90
+ end_date = date.today()
91
+ start_date = end_date - timedelta(days=30)
92
+
93
+ # Using symbol (recommended)
94
+ data = fetcher.fetch_historical_data(
95
+ ticker_token="RELIANCE",
96
+ start_date=start_date,
97
+ end_date=end_date,
98
+ timeframe="minute"
99
+ )
100
+
101
+ # Using instrument token
102
+ data = fetcher.fetch_historical_data(
103
+ ticker_token=408065, # HDFC Bank
104
+ start_date=start_date,
105
+ end_date=end_date,
106
+ timeframe="minute"
107
+ )
108
+
109
+ print(data.head())
110
+ ```
111
+
112
+ ### 3. Advanced Usage
113
+
114
+ ```python
115
+ # Custom configuration
116
+ fetcher = ZerodhaDataFetcher(
117
+ requests_per_second=3,
118
+ token_expiry_hours=6,
119
+ user_id="custom_user_id", # Override env var
120
+ password="custom_password" # Override env var
121
+ )
122
+
123
+ # Search for symbols
124
+ results = fetcher.search_symbols("HDFC", limit=5)
125
+ print(results)
126
+
127
+ # Get instrument info
128
+ info = fetcher.get_instrument_info("RELIANCE")
129
+ print(info)
130
+ ```
131
+
132
+ ## Configuration
133
+
134
+ ### Environment Variables
135
+
136
+ | Variable | Description | Required |
137
+ | ---------------------------------- | ----------------------------------- | -------- |
138
+ | `ZERODHA_USER_ID` | Your Zerodha user ID | Yes |
139
+ | `ZERODHA_PASSWORD` | Your Zerodha password | Yes |
140
+ | `ZERODHA_USER_TYPE` | Account type (individual/corporate) | Yes |
141
+ | `ZERODHA_TOTP_SECRET` | TOTP secret for 2FA | Yes |
142
+ | `ZERODHA_KEYRING_TOKEN_KEY` | Keyring token key | No |
143
+ | `ZERODHA_KEYRING_ENCRYPTION_KEY` | Keyring encryption key | No |
144
+
145
+ ### Parameters
146
+
147
+ - `requests_per_second`: API rate limit (1-10, default: 2)
148
+ - `token_expiry_hours`: Token validity period (default: 6)
149
+ - `timeframe`: Data timeframe ('minute', 'day', etc.)
150
+
151
+ ## API Reference
152
+
153
+ ### ZerodhaDataFetcher
154
+
155
+ Main class for fetching historical data.
156
+
157
+ #### Methods
158
+
159
+ - `fetch_historical_data(ticker_token, start_date, end_date, timeframe='minute')`: Fetch historical data
160
+ - `search_symbols(partial_name, limit=10)`: Search for trading symbols
161
+ - `get_instrument_info(symbol)`: Get instrument information
162
+
163
+ ## Error Handling
164
+
165
+ The package includes comprehensive error handling:
166
+
167
+ ```python
168
+ from zerodha_data_fetcher.utils.exceptions import (
169
+ ZerodhaAPIError,
170
+ AuthenticationError,
171
+ InvalidTickerError,
172
+ DataFetchError
173
+ )
174
+
175
+ try:
176
+ data = fetcher.fetch_historical_data("INVALID", start_date, end_date)
177
+ except InvalidTickerError as e:
178
+ print(f"Invalid ticker: {e}")
179
+ except AuthenticationError as e:
180
+ print(f"Auth failed: {e}")
181
+ except DataFetchError as e:
182
+ print(f"Data fetch failed: {e}")
183
+ ```
184
+
185
+ ## Contributing
186
+
187
+ 1. Fork the repository
188
+ 2. Create a feature branch
189
+ 3. Make your changes
190
+ 4. Add tests
191
+ 5. Submit a pull request
192
+
193
+ ## License
194
+
195
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
196
+
197
+ ## Disclaimer
198
+
199
+ This package is for educational and research purposes. Please ensure compliance with Zerodha's terms of service and applicable regulations when using this package.
200
+
201
+ ## Support
202
+
203
+ - 📖 [Documentation](https://github.com/JayceeGupta/Zerodha-Data-Fetcher#readme)
204
+ - 🐛 [Bug Reports](https://github.com/JayceeGupta/Zerodha-Data-Fetcher/issues)
205
+ - 💬 [Discussions](https://github.com/JayceeGupta/Zerodha-Data-Fetcher/discussions)
206
+
207
+ ```
208
+
209
+ ```
@@ -0,0 +1,162 @@
1
+ # Zerodha Data Fetcher
2
+
3
+ A Python package for fetching historical data from Zerodha API with advanced features like rate limiting, authentication management, and parallel data fetching.
4
+
5
+ ## Features
6
+
7
+ - 🚀 **Fast Parallel Data Fetching**: Concurrent requests with intelligent rate limiting
8
+ - 🔐 **Automatic Authentication**: Handles login, 2FA, and token management
9
+ - 📊 **Multiple Data Formats**: Support for minute, daily, and other timeframes
10
+ - 🛡️ **Error Handling**: Robust error handling with retry mechanisms
11
+ - 🔍 **Symbol Search**: Built-in instrument search and validation
12
+ - ⚙️ **Configurable**: Flexible configuration via environment variables or parameters
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ pip install zerodha-data-fetcher
18
+ ```
19
+
20
+ ## Quick Start
21
+
22
+ ### 1. Set up environment variables
23
+
24
+ Create a `.env` file in your project root:
25
+
26
+ ```env
27
+ ZERODHA_USER_ID=your_user_id
28
+ ZERODHA_PASSWORD=your_password
29
+ ZERODHA_USER_TYPE=individual
30
+ ZERODHA_TOTP_SECRET=your_totp_secret
31
+ ```
32
+
33
+ ### 2. Basic Usage
34
+
35
+ ```python
36
+ from zerodha_data_fetcher import ZerodhaDataFetcher
37
+ from datetime import date, timedelta
38
+
39
+ # Initialize the fetcher
40
+ fetcher = ZerodhaDataFetcher(requests_per_second=2)
41
+
42
+ # Fetch historical data
43
+ end_date = date.today()
44
+ start_date = end_date - timedelta(days=30)
45
+
46
+ # Using symbol (recommended)
47
+ data = fetcher.fetch_historical_data(
48
+ ticker_token="RELIANCE",
49
+ start_date=start_date,
50
+ end_date=end_date,
51
+ timeframe="minute"
52
+ )
53
+
54
+ # Using instrument token
55
+ data = fetcher.fetch_historical_data(
56
+ ticker_token=408065, # HDFC Bank
57
+ start_date=start_date,
58
+ end_date=end_date,
59
+ timeframe="minute"
60
+ )
61
+
62
+ print(data.head())
63
+ ```
64
+
65
+ ### 3. Advanced Usage
66
+
67
+ ```python
68
+ # Custom configuration
69
+ fetcher = ZerodhaDataFetcher(
70
+ requests_per_second=3,
71
+ token_expiry_hours=6,
72
+ user_id="custom_user_id", # Override env var
73
+ password="custom_password" # Override env var
74
+ )
75
+
76
+ # Search for symbols
77
+ results = fetcher.search_symbols("HDFC", limit=5)
78
+ print(results)
79
+
80
+ # Get instrument info
81
+ info = fetcher.get_instrument_info("RELIANCE")
82
+ print(info)
83
+ ```
84
+
85
+ ## Configuration
86
+
87
+ ### Environment Variables
88
+
89
+ | Variable | Description | Required |
90
+ | ---------------------------------- | ----------------------------------- | -------- |
91
+ | `ZERODHA_USER_ID` | Your Zerodha user ID | Yes |
92
+ | `ZERODHA_PASSWORD` | Your Zerodha password | Yes |
93
+ | `ZERODHA_USER_TYPE` | Account type (individual/corporate) | Yes |
94
+ | `ZERODHA_TOTP_SECRET` | TOTP secret for 2FA | Yes |
95
+ | `ZERODHA_KEYRING_TOKEN_KEY` | Keyring token key | No |
96
+ | `ZERODHA_KEYRING_ENCRYPTION_KEY` | Keyring encryption key | No |
97
+
98
+ ### Parameters
99
+
100
+ - `requests_per_second`: API rate limit (1-10, default: 2)
101
+ - `token_expiry_hours`: Token validity period (default: 6)
102
+ - `timeframe`: Data timeframe ('minute', 'day', etc.)
103
+
104
+ ## API Reference
105
+
106
+ ### ZerodhaDataFetcher
107
+
108
+ Main class for fetching historical data.
109
+
110
+ #### Methods
111
+
112
+ - `fetch_historical_data(ticker_token, start_date, end_date, timeframe='minute')`: Fetch historical data
113
+ - `search_symbols(partial_name, limit=10)`: Search for trading symbols
114
+ - `get_instrument_info(symbol)`: Get instrument information
115
+
116
+ ## Error Handling
117
+
118
+ The package includes comprehensive error handling:
119
+
120
+ ```python
121
+ from zerodha_data_fetcher.utils.exceptions import (
122
+ ZerodhaAPIError,
123
+ AuthenticationError,
124
+ InvalidTickerError,
125
+ DataFetchError
126
+ )
127
+
128
+ try:
129
+ data = fetcher.fetch_historical_data("INVALID", start_date, end_date)
130
+ except InvalidTickerError as e:
131
+ print(f"Invalid ticker: {e}")
132
+ except AuthenticationError as e:
133
+ print(f"Auth failed: {e}")
134
+ except DataFetchError as e:
135
+ print(f"Data fetch failed: {e}")
136
+ ```
137
+
138
+ ## Contributing
139
+
140
+ 1. Fork the repository
141
+ 2. Create a feature branch
142
+ 3. Make your changes
143
+ 4. Add tests
144
+ 5. Submit a pull request
145
+
146
+ ## License
147
+
148
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
149
+
150
+ ## Disclaimer
151
+
152
+ This package is for educational and research purposes. Please ensure compliance with Zerodha's terms of service and applicable regulations when using this package.
153
+
154
+ ## Support
155
+
156
+ - 📖 [Documentation](https://github.com/JayceeGupta/Zerodha-Data-Fetcher#readme)
157
+ - 🐛 [Bug Reports](https://github.com/JayceeGupta/Zerodha-Data-Fetcher/issues)
158
+ - 💬 [Discussions](https://github.com/JayceeGupta/Zerodha-Data-Fetcher/discussions)
159
+
160
+ ```
161
+
162
+ ```
@@ -0,0 +1,87 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "zerodha-data-fetcher"
7
+ version = "1.0.0"
8
+ description = "A Python package for fetching historical data from Zerodha API"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ license-files = ["LICENSE"]
12
+ authors = [
13
+ {name = "Jayam Gupta", email = "guptajayam47@gmail.com"}
14
+ ]
15
+ maintainers = [
16
+ {name = "Jayam Gupta", email = "guptajayam47@gmail.com"}
17
+ ]
18
+ keywords = ["zerodha", "trading", "data", "api", "historical", "stock-market"]
19
+ classifiers = [
20
+ "Development Status :: 4 - Beta",
21
+ "Intended Audience :: Developers",
22
+ "Intended Audience :: Financial and Insurance Industry",
23
+ "Operating System :: OS Independent",
24
+ "Programming Language :: Python :: 3",
25
+ "Programming Language :: Python :: 3.8",
26
+ "Programming Language :: Python :: 3.9",
27
+ "Programming Language :: Python :: 3.10",
28
+ "Programming Language :: Python :: 3.11",
29
+ "Programming Language :: Python :: 3.12",
30
+ "Topic :: Office/Business :: Financial",
31
+ "Topic :: Software Development :: Libraries :: Python Modules",
32
+ ]
33
+ requires-python = ">=3.8"
34
+ dependencies = [
35
+ "requests>=2.25.0",
36
+ "pandas>=1.3.0",
37
+ "python-dateutil>=2.8.0",
38
+ "pyotp>=2.6.0",
39
+ "keyring>=23.0.0",
40
+ "cryptography>=3.4.0",
41
+ "Brotli>=1.0.9",
42
+ ]
43
+
44
+ [project.optional-dependencies]
45
+ dev = [
46
+ "pytest>=6.0",
47
+ "pytest-cov>=2.0",
48
+ "black>=21.0",
49
+ "flake8>=3.9",
50
+ "mypy>=0.910",
51
+ "pre-commit>=2.15",
52
+ ]
53
+ docs = [
54
+ "sphinx>=4.0",
55
+ "sphinx-rtd-theme>=1.0",
56
+ "myst-parser>=0.15",
57
+ ]
58
+
59
+ [project.urls]
60
+ Homepage = "https://github.com/JayceeGupta/Zerodha-Data-Fetcher"
61
+ Repository = "https://github.com/JayceeGupta/Zerodha-Data-Fetcher"
62
+ Documentation = "https://github.com/JayceeGupta/Zerodha-Data-Fetcher#readme"
63
+ "Bug Tracker" = "https://github.com/JayceeGupta/Zerodha-Data-Fetcher/issues"
64
+
65
+ [tool.setuptools.packages.find]
66
+ where = ["src"]
67
+
68
+ [tool.setuptools.package-data]
69
+ zerodha_data_fetcher = ["utils/data/*.csv", "utils/data/*.json"]
70
+
71
+ [tool.black]
72
+ line-length = 88
73
+ target-version = ['py38']
74
+ include = '\.pyi?$'
75
+
76
+ [tool.mypy]
77
+ python_version = "3.8"
78
+ warn_return_any = true
79
+ warn_unused_configs = true
80
+ disallow_untyped_defs = true
81
+
82
+ [tool.pytest.ini_options]
83
+ testpaths = ["tests"]
84
+ python_files = ["test_*.py"]
85
+ python_classes = ["Test*"]
86
+ python_functions = ["test_*"]
87
+ addopts = "-v --cov=zerodha_data_fetcher --cov-report=html --cov-report=term-missing"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,6 @@
1
+ """Setup script for zerodha-data-fetcher package."""
2
+
3
+ from setuptools import setup
4
+
5
+ # Use pyproject.toml for configuration
6
+ setup()
@@ -0,0 +1,24 @@
1
+ """Zerodha Data Fetcher - A Python package for fetching historical data from Zerodha API."""
2
+
3
+ __version__ = "1.0.0"
4
+ __author__ = "Your Name"
5
+ __email__ = "your.email@example.com"
6
+
7
+ # Import main classes and functions for easy access
8
+ try:
9
+ from .core.data_fetcher import ZerodhaDataFetcher, fetchDataZerodha
10
+ from .utils.logging_config import setup_logging
11
+ from .utils.config import Config
12
+
13
+ __all__ = [
14
+ "ZerodhaDataFetcher",
15
+ "fetchDataZerodha",
16
+ "setup_logging",
17
+ "Config",
18
+ "__version__"
19
+ ]
20
+ except ImportError as e:
21
+ # Handle import errors gracefully during development
22
+ import warnings
23
+ warnings.warn(f"Some imports failed: {e}")
24
+ __all__ = ["__version__"]
@@ -0,0 +1,43 @@
1
+ # """Core functionality for Zerodha Data Fetcher."""
2
+
3
+ # from .data_fetcher import ZerodhaDataFetcher
4
+ # from .auth import AuthenticationManager
5
+ # from .token_generator import ZerodhaTokenGenerator, getEncAuthToken, get_TOTP
6
+ # from .instrument_manager import ZerodhaInstrumentManager, fetchZerodhaID
7
+ # from .rate_limiter import RateLimitedThreadPoolExecutor
8
+
9
+ # __all__ = [
10
+ # "ZerodhaDataFetcher",
11
+ # "AuthenticationManager",
12
+ # "ZerodhaTokenGenerator",
13
+ # "ZerodhaInstrumentManager",
14
+ # "RateLimitedThreadPoolExecutor",
15
+ # "getEncAuthToken", # Backward compatibility
16
+ # "get_TOTP", # Backward compatibility
17
+ # "fetchZerodhaID" # Backward compatibility
18
+ # ]
19
+
20
+
21
+ """
22
+ Core modules for Zerodha Data Fetcher.
23
+
24
+ This module contains the main functionality:
25
+ - Data fetching and processing
26
+ - Authentication management
27
+ - Rate limiting
28
+ - Instrument management
29
+ """
30
+
31
+ from .data_fetcher import ZerodhaDataFetcher, fetchDataZerodha
32
+ from .instrument_manager import ZerodhaInstrumentManager, fetchZerodhaID
33
+ from .auth import AuthenticationManager
34
+ from .rate_limiter import RateLimitedThreadPoolExecutor
35
+
36
+ __all__ = [
37
+ "ZerodhaDataFetcher",
38
+ "fetchDataZerodha",
39
+ "ZerodhaInstrumentManager",
40
+ "fetchZerodhaID",
41
+ "AuthenticationManager",
42
+ "RateLimitedThreadPoolExecutor",
43
+ ]
@@ -0,0 +1,101 @@
1
+ """Authentication management for Zerodha API."""
2
+
3
+ import os
4
+ import time
5
+ import logging
6
+ from datetime import date
7
+ from typing import Optional
8
+
9
+ import keyring
10
+
11
+ from ..utils.config import Config
12
+ from ..utils.exceptions import AuthenticationError, TokenExpiredError
13
+ from ..utils.encryption import TokenEncryption
14
+ from .token_generator import ZerodhaTokenGenerator
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+
19
+ class AuthenticationManager:
20
+ """Manages authentication tokens for Zerodha API."""
21
+
22
+ def __init__(self, token_expiry_hours: float = Config.DEFAULT_TOKEN_EXPIRY_HOURS, config: Optional['Config'] = None):
23
+ self.token_expiry_hours = token_expiry_hours
24
+ self.config = config or Config()
25
+ self.token_key = self.config.ZERODHA_KEYRING_TOKEN_KEY
26
+ self.token_generator = ZerodhaTokenGenerator(config=self.config)
27
+
28
+ def get_auth_token(self) -> str:
29
+ """
30
+ Retrieves an authentication token for accessing the Zerodha API.
31
+
32
+ Returns:
33
+ str: The authentication token.
34
+
35
+ Raises:
36
+ AuthenticationError: If token generation fails.
37
+ """
38
+ try:
39
+ expiry_seconds = self.token_expiry_hours * 3600
40
+ today = date.today().strftime('%Y-%m-%d')
41
+ current_time = time.time()
42
+
43
+ logger.debug(f"Getting auth token for date: {today}")
44
+
45
+ # Try to retrieve stored token
46
+ encrypted_token = keyring.get_password(self.token_key, "token")
47
+ token_date = keyring.get_password(self.token_key, "date")
48
+ token_timestamp = keyring.get_password(self.token_key, "timestamp")
49
+
50
+ if encrypted_token and token_date and token_timestamp:
51
+ logger.info("Found token data in keyring")
52
+ time_elapsed = current_time - float(token_timestamp)
53
+ logger.info(f"Time elapsed since last token: {time_elapsed} seconds")
54
+ logger.info(f"Token expiry time: {expiry_seconds} seconds")
55
+ if token_date == today and time_elapsed < expiry_seconds:
56
+ logger.info("Found valid token for today")
57
+ return TokenEncryption.decrypt_token(encrypted_token)
58
+ else:
59
+ logger.debug("Stored token is outdated")
60
+ else:
61
+ logger.debug("No valid token data found in keyring")
62
+
63
+ except Exception as e:
64
+ logger.error(f"Error retrieving token: {str(e)}")
65
+
66
+ # Generate new token
67
+ return self._generate_new_token()
68
+
69
+ def _generate_new_token(self) -> str:
70
+ """Generate and store a new authentication token."""
71
+ logger.info("Generating new auth token")
72
+
73
+ try:
74
+ new_token = self.token_generator.generate_auth_token()
75
+ encrypted_token = TokenEncryption.encrypt_token(new_token)
76
+
77
+ # Store the new token
78
+ today = date.today().strftime('%Y-%m-%d')
79
+ current_time = time.time()
80
+
81
+ keyring.set_password(self.token_key, "token", encrypted_token)
82
+ keyring.set_password(self.token_key, "date", today)
83
+ keyring.set_password(self.token_key, "timestamp", str(current_time))
84
+ keyring.set_password(self.token_key, "userid", self.config.get_user_id())
85
+
86
+ logger.info("Successfully saved new token to keyring")
87
+ return new_token
88
+
89
+ except Exception as e:
90
+ logger.error(f"Failed to generate/save token: {str(e)}")
91
+ raise AuthenticationError(f"Token generation failed: {str(e)}")
92
+
93
+ def invalidate_token(self) -> None:
94
+ """Invalidate the current stored token."""
95
+ try:
96
+ keyring.delete_password(self.token_key, "token")
97
+ keyring.delete_password(self.token_key, "date")
98
+ keyring.delete_password(self.token_key, "timestamp")
99
+ logger.info("Token invalidated successfully")
100
+ except Exception as e:
101
+ logger.warning(f"Failed to invalidate token: {str(e)}")