nse-xbrl-parser 0.1.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 (25) hide show
  1. nse_xbrl_parser-0.1.0/PKG-INFO +197 -0
  2. nse_xbrl_parser-0.1.0/README.md +178 -0
  3. nse_xbrl_parser-0.1.0/pyproject.toml +45 -0
  4. nse_xbrl_parser-0.1.0/pyproject.toml.orig +45 -0
  5. nse_xbrl_parser-0.1.0/src/nse_xbrl_parser/__init__.py +86 -0
  6. nse_xbrl_parser-0.1.0/src/nse_xbrl_parser/client/__init__.py +10 -0
  7. nse_xbrl_parser-0.1.0/src/nse_xbrl_parser/client/nse_client.py +93 -0
  8. nse_xbrl_parser-0.1.0/src/nse_xbrl_parser/core/__init__.py +21 -0
  9. nse_xbrl_parser-0.1.0/src/nse_xbrl_parser/core/context.py +63 -0
  10. nse_xbrl_parser-0.1.0/src/nse_xbrl_parser/core/models.py +131 -0
  11. nse_xbrl_parser-0.1.0/src/nse_xbrl_parser/core/parser.py +264 -0
  12. nse_xbrl_parser-0.1.0/src/nse_xbrl_parser/core/unit.py +35 -0
  13. nse_xbrl_parser-0.1.0/src/nse_xbrl_parser/taxonomy/__init__.py +21 -0
  14. nse_xbrl_parser-0.1.0/src/nse_xbrl_parser/taxonomy/downloader.py +101 -0
  15. nse_xbrl_parser-0.1.0/src/nse_xbrl_parser/taxonomy/linkbase.py +104 -0
  16. nse_xbrl_parser-0.1.0/src/nse_xbrl_parser/taxonomy/registry.py +100 -0
  17. nse_xbrl_parser-0.1.0/src/nse_xbrl_parser/taxonomy/schema.py +79 -0
  18. nse_xbrl_parser-0.1.0/src/nse_xbrl_parser/taxonomy/taxonomies.json +843 -0
  19. nse_xbrl_parser-0.1.0/src/nse_xbrl_parser/typed/__init__.py +18 -0
  20. nse_xbrl_parser-0.1.0/src/nse_xbrl_parser/typed/corporate_governance.py +55 -0
  21. nse_xbrl_parser-0.1.0/src/nse_xbrl_parser/typed/financial_results.py +216 -0
  22. nse_xbrl_parser-0.1.0/src/nse_xbrl_parser/typed/shareholding.py +76 -0
  23. nse_xbrl_parser-0.1.0/src/nse_xbrl_parser/utils/__init__.py +17 -0
  24. nse_xbrl_parser-0.1.0/src/nse_xbrl_parser/utils/dates.py +34 -0
  25. nse_xbrl_parser-0.1.0/src/nse_xbrl_parser/utils/xml_utils.py +50 -0
@@ -0,0 +1,197 @@
1
+ Metadata-Version: 2.3
2
+ Name: nse-xbrl-parser
3
+ Version: 0.1.0
4
+ Summary: Async Python 3.14 library for parsing XBRL Filing Information of NSE & BSE across all taxonomies
5
+ Author: innerkorehq
6
+ Requires-Dist: aiohttp>=3.9.0
7
+ Requires-Dist: lxml>=5.2.0
8
+ Requires-Dist: pydantic>=2.7.0
9
+ Requires-Dist: python-dateutil>=2.9.0
10
+ Requires-Dist: pytest>=8.0.0 ; extra == 'dev'
11
+ Requires-Dist: pytest-asyncio>=0.23.0 ; extra == 'dev'
12
+ Requires-Python: >=3.12
13
+ Project-URL: Homepage, https://github.com/innerkorehq/nse-xbrl
14
+ Project-URL: Documentation, https://innerkorehq.github.io/nse-xbrl/
15
+ Project-URL: Repository, https://github.com/innerkorehq/nse-xbrl
16
+ Project-URL: Issues, https://github.com/innerkorehq/nse-xbrl/issues
17
+ Provides-Extra: dev
18
+ Description-Content-Type: text/markdown
19
+
20
+ # nse-xbrl
21
+
22
+ [![Documentation](https://img.shields.io/badge/docs-online-blue.svg)](https://innerkorehq.github.io/nse-xbrl/)
23
+ [![Python 3.12 | 3.13 | 3.14](https://img.shields.io/badge/python-3.12%20|%203.13%20|%203.14-blue.svg)](https://github.com/innerkorehq/nse-xbrl)
24
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
25
+
26
+ Modern Asynchronous Python 3.14 library for parsing XBRL Filing Information across **all 58 taxonomies** of the National Stock Exchange of India (NSE) and Bombay Stock Exchange (BSE).
27
+
28
+ 📖 **[Read the Documentation](https://innerkorehq.github.io/nse-xbrl/)**
29
+
30
+ ---
31
+
32
+ ## Features
33
+
34
+ - **Universal XBRL 2.1 & Dimensions Parser**:
35
+ - Asynchronous stream and file parsing using Python 3.14 native `asyncio` and `lxml`.
36
+ - Automatically resolves contexts (`instant`, `duration`), entity identifiers (CIN, Scrip Code), units (`INR`, `shares`, ratios), and dimensional segments.
37
+ - Zero requirement for custom parsers per filing type—parses *any* NSE/BSE filing format.
38
+ - **Coverage of all 58 NSE & BSE Taxonomies**:
39
+ - Built-in catalog indexing all 58 taxonomies from [NSE XBRL Information Portal](https://www.nseindia.com/static/companies-listing/xbrl-information).
40
+ - Automatically downloads and caches official schemas (`.xsd`), label linkbases (`*-lab.xml`), calculations, and presentations.
41
+ - **High-Level Typed Model Adapters**:
42
+ - `FinancialResultsModel`: Regulation 33 Financial Results (`Ind AS`, `Banking`, `NBFC`, `Insurance`, `Integrated Filings`).
43
+ - `ShareholdingPatternModel`: Regulation 31 Shareholding Patterns with promoter & public breakdown.
44
+ - `CorporateGovernanceModel`: Regulation 27(2) Board composition & committee details.
45
+ - **Async HTTP Client (`AsyncNSEClient`)**:
46
+ - Automated download and extraction of filing ZIP packages and instance XML documents.
47
+
48
+ ---
49
+
50
+ ## Installation
51
+
52
+ ```bash
53
+ # Using uv (recommended)
54
+ uv add nse-xbrl-parser
55
+
56
+ # Or with pip
57
+ pip install nse-xbrl-parser
58
+ ```
59
+
60
+ ---
61
+
62
+ ## Quickstart
63
+
64
+ ### 1. Parse an XBRL Filing Asynchronously
65
+
66
+ ```python
67
+ import asyncio
68
+ from nse_xbrl_parser import parse_file, FinancialResultsModel
69
+
70
+ async def main():
71
+ # Parse any filing XML
72
+ instance = await parse_file("RELIANCE_Financial_Results.xml")
73
+
74
+ # Universal Fact Lookups
75
+ print("Company:", instance.get_fact_value("NameOfTheCompany"))
76
+ print("Scrip Code:", instance.get_fact_value("ScripCode"))
77
+ print("Revenue:", instance.get_fact_float("RevenueFromOperations"))
78
+
79
+ # Convert to Strongly-Typed Model
80
+ results = FinancialResultsModel.from_instance(instance)
81
+ print(f"PAT: ₹{results.profit_after_tax:,.2f}")
82
+ print(f"EBITDA: ₹{results.ebitda:,.2f}")
83
+ print(f"Basic EPS: ₹{results.basic_eps:.2f}")
84
+
85
+ asyncio.run(main())
86
+ ```
87
+
88
+ ### 2. Inspect Any of the 58 NSE/BSE Taxonomies
89
+
90
+ ```python
91
+ import asyncio
92
+ from nse_xbrl_parser import TaxonomyRegistry, AsyncTaxonomyDownloader
93
+
94
+ async def main():
95
+ registry = TaxonomyRegistry()
96
+
97
+ # Total 58 taxonomies registered
98
+ print("Total Taxonomies:", registry.count())
99
+
100
+ # Get Regulation 31 Shareholding Pattern Taxonomy (ID 4)
101
+ shp_tax = registry.get_by_id(4)
102
+ print(shp_tax.name)
103
+ print("Download URL:", shp_tax.primary_taxonomy_url)
104
+
105
+ # Download schema & label linkbase on the fly
106
+ downloader = AsyncTaxonomyDownloader()
107
+ schema, linkbase = await downloader.load_taxonomy_metadata(shp_tax)
108
+
109
+ print(f"Total concepts declared: {len(schema.elements)}")
110
+ print("Human friendly label:", linkbase.get_label("PublicShareholdingAsAPercentageOfTotalNumberOfShares"))
111
+
112
+ asyncio.run(main())
113
+ ```
114
+
115
+ ### 3. Parse Shareholding Patterns & Corporate Governance
116
+
117
+ ```python
118
+ from nse_xbrl_parser import parse_xbrl_sync, ShareholdingPatternModel, CorporateGovernanceModel
119
+
120
+ xml_content = open("TCS_SHP.xml", "rb").read()
121
+ instance = parse_xbrl_sync(xml_content)
122
+
123
+ shp = ShareholdingPatternModel.from_instance(instance)
124
+ print(f"Promoter Holding: {shp.promoter_holding_percentage}%")
125
+ print(f"Public Holding: {shp.public_holding_percentage}%")
126
+ ```
127
+
128
+ ---
129
+
130
+ ## Supported Taxonomies (All 58 Categories)
131
+
132
+ 1. `Regulation 13 (3)` - Statement of Investor complaints
133
+ 2. `Investor complaints` - REITs / InvITs
134
+ 3. `Regulation 27 (2)` - Corporate Governance
135
+ 4. `Regulation 31` - Shareholding Pattern
136
+ 5. `Reconciliation of Share Capital Audit`
137
+ 6. `Regulation 33` - Financial Results - Ind AS & Integrated Filing
138
+ 7. `Regulation 33` - Financial Results - Other than Banks
139
+ 8. `Regulation 33` - Financial Results - REITs / InvITs
140
+ 9. `Regulation 33` - Financial Results - General Insurance
141
+ 10. `Regulation 33` - Financial Results - Life Insurance
142
+ 11. `Regulation 33` - Financial Results - Banking
143
+ 12. `Regulation 33` - Financial Results - NBFC
144
+ 13. `Regulation 44` - Voting Results
145
+ 14. `Regulation 7(2) & 7(3)` - Insider Trading
146
+ 15. `Regulation 32 (1)` - Statement of Deviation/Variation
147
+ 16. `Regulation 24A` - Secretarial Compliance Report
148
+ 17. `Regulation 60` - Record Date / Book Closure
149
+ 18. `Unit Holding Pattern`
150
+ 19. `Regulation 23 (9)` - Related Party Transactions
151
+ 20. `Business Responsibility and Sustainability Reporting (BRSR)`
152
+ 21. `Credit Rating`
153
+ 22. `Default History Information`
154
+ 23. `Interest Payment`
155
+ 24. `Redemption Payment`
156
+ 25. `Regulation 50` - Prior Intimation of Board Meeting
157
+ 26. `Regulation 29` - Prior Intimation of Board Meeting
158
+ 27. `Regulation 30` - Change in Directors / KMP / SMP / Auditor
159
+ 28. `Regulation 30` - Acquisitions / Scheme of Arrangement / Restructuring
160
+ 29. `Regulation 30` - Outcome of Board Meeting (Dividend, Bonus, Buyback)
161
+ 30. `Regulation 30` - Issuance / Forfeiture / Alteration of Securities
162
+ 31. `Regulation 30` - Material Agreements / Joint Ventures
163
+ 32. `Regulation 30` - Fraud / Defaults / Arrests
164
+ 33. `Regulation 30` - One Time Settlement (OTS)
165
+ 34. `Regulation 30` - Resolution Plan / Debt Restructuring
166
+ 35. `Regulation 30` - Notice of Shareholders Meeting
167
+ 36. `Regulation 30` - Closure of Trading Window
168
+ 37. `Regulation 39` - Loss of Share Certificate / Duplicate Issue
169
+ 38. `Regulation 30` - Corporate Insolvency Resolution Process (CIRP)
170
+ 39. `Regulation 33` - Statement on Impact of Audit Qualifications
171
+ 40. `Insider Trading Plan`
172
+ 41. `Integrated Filing - Governance`
173
+ 42. `Regulation 30` - Awarding / Bagging of Orders
174
+ 43. `ISD` - Buy-back from Open Market Route
175
+ 44. `ISD` - Buy-back through Tender Offer Route
176
+ 45. `Initial Public Offer (IPO)` - In-principle
177
+ 46. `ADR / GDR` - In-principle and Post Allotment
178
+ 47. `FCCB` - In-principle and Post Allotment
179
+ 48. `Preferential Issue` - In-principle and Post Allotment
180
+ 49. `QIP` - In-principle and Post Allotment
181
+ 50. `Rights Issue` - In-principle and Post Allotment
182
+ 51. `Initial Public Offer (IPO)` - Final Listing
183
+ 52. `Resignation of Director / KMP / SMP / Compliance Officer`
184
+ 53. `Regulation 30` - Resignation of Statutory Auditor
185
+ 54. `Regulation 30` - Forensic Audit
186
+ 55. `Regulation 30` - Actions initiated / taken or orders passed
187
+ 56. `Regulation 30` - Analyst / Investor Meet
188
+ 57. `Violation of Code of Conduct` (Insider Trading)
189
+ 58. `Regulation 30` - Para B of Part A of Schedule III
190
+
191
+ ---
192
+
193
+ ## Testing
194
+
195
+ ```bash
196
+ uv run pytest
197
+ ```
@@ -0,0 +1,178 @@
1
+ # nse-xbrl
2
+
3
+ [![Documentation](https://img.shields.io/badge/docs-online-blue.svg)](https://innerkorehq.github.io/nse-xbrl/)
4
+ [![Python 3.12 | 3.13 | 3.14](https://img.shields.io/badge/python-3.12%20|%203.13%20|%203.14-blue.svg)](https://github.com/innerkorehq/nse-xbrl)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+
7
+ Modern Asynchronous Python 3.14 library for parsing XBRL Filing Information across **all 58 taxonomies** of the National Stock Exchange of India (NSE) and Bombay Stock Exchange (BSE).
8
+
9
+ 📖 **[Read the Documentation](https://innerkorehq.github.io/nse-xbrl/)**
10
+
11
+ ---
12
+
13
+ ## Features
14
+
15
+ - **Universal XBRL 2.1 & Dimensions Parser**:
16
+ - Asynchronous stream and file parsing using Python 3.14 native `asyncio` and `lxml`.
17
+ - Automatically resolves contexts (`instant`, `duration`), entity identifiers (CIN, Scrip Code), units (`INR`, `shares`, ratios), and dimensional segments.
18
+ - Zero requirement for custom parsers per filing type—parses *any* NSE/BSE filing format.
19
+ - **Coverage of all 58 NSE & BSE Taxonomies**:
20
+ - Built-in catalog indexing all 58 taxonomies from [NSE XBRL Information Portal](https://www.nseindia.com/static/companies-listing/xbrl-information).
21
+ - Automatically downloads and caches official schemas (`.xsd`), label linkbases (`*-lab.xml`), calculations, and presentations.
22
+ - **High-Level Typed Model Adapters**:
23
+ - `FinancialResultsModel`: Regulation 33 Financial Results (`Ind AS`, `Banking`, `NBFC`, `Insurance`, `Integrated Filings`).
24
+ - `ShareholdingPatternModel`: Regulation 31 Shareholding Patterns with promoter & public breakdown.
25
+ - `CorporateGovernanceModel`: Regulation 27(2) Board composition & committee details.
26
+ - **Async HTTP Client (`AsyncNSEClient`)**:
27
+ - Automated download and extraction of filing ZIP packages and instance XML documents.
28
+
29
+ ---
30
+
31
+ ## Installation
32
+
33
+ ```bash
34
+ # Using uv (recommended)
35
+ uv add nse-xbrl-parser
36
+
37
+ # Or with pip
38
+ pip install nse-xbrl-parser
39
+ ```
40
+
41
+ ---
42
+
43
+ ## Quickstart
44
+
45
+ ### 1. Parse an XBRL Filing Asynchronously
46
+
47
+ ```python
48
+ import asyncio
49
+ from nse_xbrl_parser import parse_file, FinancialResultsModel
50
+
51
+ async def main():
52
+ # Parse any filing XML
53
+ instance = await parse_file("RELIANCE_Financial_Results.xml")
54
+
55
+ # Universal Fact Lookups
56
+ print("Company:", instance.get_fact_value("NameOfTheCompany"))
57
+ print("Scrip Code:", instance.get_fact_value("ScripCode"))
58
+ print("Revenue:", instance.get_fact_float("RevenueFromOperations"))
59
+
60
+ # Convert to Strongly-Typed Model
61
+ results = FinancialResultsModel.from_instance(instance)
62
+ print(f"PAT: ₹{results.profit_after_tax:,.2f}")
63
+ print(f"EBITDA: ₹{results.ebitda:,.2f}")
64
+ print(f"Basic EPS: ₹{results.basic_eps:.2f}")
65
+
66
+ asyncio.run(main())
67
+ ```
68
+
69
+ ### 2. Inspect Any of the 58 NSE/BSE Taxonomies
70
+
71
+ ```python
72
+ import asyncio
73
+ from nse_xbrl_parser import TaxonomyRegistry, AsyncTaxonomyDownloader
74
+
75
+ async def main():
76
+ registry = TaxonomyRegistry()
77
+
78
+ # Total 58 taxonomies registered
79
+ print("Total Taxonomies:", registry.count())
80
+
81
+ # Get Regulation 31 Shareholding Pattern Taxonomy (ID 4)
82
+ shp_tax = registry.get_by_id(4)
83
+ print(shp_tax.name)
84
+ print("Download URL:", shp_tax.primary_taxonomy_url)
85
+
86
+ # Download schema & label linkbase on the fly
87
+ downloader = AsyncTaxonomyDownloader()
88
+ schema, linkbase = await downloader.load_taxonomy_metadata(shp_tax)
89
+
90
+ print(f"Total concepts declared: {len(schema.elements)}")
91
+ print("Human friendly label:", linkbase.get_label("PublicShareholdingAsAPercentageOfTotalNumberOfShares"))
92
+
93
+ asyncio.run(main())
94
+ ```
95
+
96
+ ### 3. Parse Shareholding Patterns & Corporate Governance
97
+
98
+ ```python
99
+ from nse_xbrl_parser import parse_xbrl_sync, ShareholdingPatternModel, CorporateGovernanceModel
100
+
101
+ xml_content = open("TCS_SHP.xml", "rb").read()
102
+ instance = parse_xbrl_sync(xml_content)
103
+
104
+ shp = ShareholdingPatternModel.from_instance(instance)
105
+ print(f"Promoter Holding: {shp.promoter_holding_percentage}%")
106
+ print(f"Public Holding: {shp.public_holding_percentage}%")
107
+ ```
108
+
109
+ ---
110
+
111
+ ## Supported Taxonomies (All 58 Categories)
112
+
113
+ 1. `Regulation 13 (3)` - Statement of Investor complaints
114
+ 2. `Investor complaints` - REITs / InvITs
115
+ 3. `Regulation 27 (2)` - Corporate Governance
116
+ 4. `Regulation 31` - Shareholding Pattern
117
+ 5. `Reconciliation of Share Capital Audit`
118
+ 6. `Regulation 33` - Financial Results - Ind AS & Integrated Filing
119
+ 7. `Regulation 33` - Financial Results - Other than Banks
120
+ 8. `Regulation 33` - Financial Results - REITs / InvITs
121
+ 9. `Regulation 33` - Financial Results - General Insurance
122
+ 10. `Regulation 33` - Financial Results - Life Insurance
123
+ 11. `Regulation 33` - Financial Results - Banking
124
+ 12. `Regulation 33` - Financial Results - NBFC
125
+ 13. `Regulation 44` - Voting Results
126
+ 14. `Regulation 7(2) & 7(3)` - Insider Trading
127
+ 15. `Regulation 32 (1)` - Statement of Deviation/Variation
128
+ 16. `Regulation 24A` - Secretarial Compliance Report
129
+ 17. `Regulation 60` - Record Date / Book Closure
130
+ 18. `Unit Holding Pattern`
131
+ 19. `Regulation 23 (9)` - Related Party Transactions
132
+ 20. `Business Responsibility and Sustainability Reporting (BRSR)`
133
+ 21. `Credit Rating`
134
+ 22. `Default History Information`
135
+ 23. `Interest Payment`
136
+ 24. `Redemption Payment`
137
+ 25. `Regulation 50` - Prior Intimation of Board Meeting
138
+ 26. `Regulation 29` - Prior Intimation of Board Meeting
139
+ 27. `Regulation 30` - Change in Directors / KMP / SMP / Auditor
140
+ 28. `Regulation 30` - Acquisitions / Scheme of Arrangement / Restructuring
141
+ 29. `Regulation 30` - Outcome of Board Meeting (Dividend, Bonus, Buyback)
142
+ 30. `Regulation 30` - Issuance / Forfeiture / Alteration of Securities
143
+ 31. `Regulation 30` - Material Agreements / Joint Ventures
144
+ 32. `Regulation 30` - Fraud / Defaults / Arrests
145
+ 33. `Regulation 30` - One Time Settlement (OTS)
146
+ 34. `Regulation 30` - Resolution Plan / Debt Restructuring
147
+ 35. `Regulation 30` - Notice of Shareholders Meeting
148
+ 36. `Regulation 30` - Closure of Trading Window
149
+ 37. `Regulation 39` - Loss of Share Certificate / Duplicate Issue
150
+ 38. `Regulation 30` - Corporate Insolvency Resolution Process (CIRP)
151
+ 39. `Regulation 33` - Statement on Impact of Audit Qualifications
152
+ 40. `Insider Trading Plan`
153
+ 41. `Integrated Filing - Governance`
154
+ 42. `Regulation 30` - Awarding / Bagging of Orders
155
+ 43. `ISD` - Buy-back from Open Market Route
156
+ 44. `ISD` - Buy-back through Tender Offer Route
157
+ 45. `Initial Public Offer (IPO)` - In-principle
158
+ 46. `ADR / GDR` - In-principle and Post Allotment
159
+ 47. `FCCB` - In-principle and Post Allotment
160
+ 48. `Preferential Issue` - In-principle and Post Allotment
161
+ 49. `QIP` - In-principle and Post Allotment
162
+ 50. `Rights Issue` - In-principle and Post Allotment
163
+ 51. `Initial Public Offer (IPO)` - Final Listing
164
+ 52. `Resignation of Director / KMP / SMP / Compliance Officer`
165
+ 53. `Regulation 30` - Resignation of Statutory Auditor
166
+ 54. `Regulation 30` - Forensic Audit
167
+ 55. `Regulation 30` - Actions initiated / taken or orders passed
168
+ 56. `Regulation 30` - Analyst / Investor Meet
169
+ 57. `Violation of Code of Conduct` (Insider Trading)
170
+ 58. `Regulation 30` - Para B of Part A of Schedule III
171
+
172
+ ---
173
+
174
+ ## Testing
175
+
176
+ ```bash
177
+ uv run pytest
178
+ ```
@@ -0,0 +1,45 @@
1
+ [project]
2
+ name = "nse-xbrl-parser"
3
+ version = "0.1.0"
4
+ description = "Async Python 3.14 library for parsing XBRL Filing Information of NSE & BSE across all taxonomies"
5
+ readme = "README.md"
6
+ requires-python = ">=3.12"
7
+ dependencies = [
8
+ "aiohttp>=3.9.0",
9
+ "lxml>=5.2.0",
10
+ "pydantic>=2.7.0",
11
+ "python-dateutil>=2.9.0",
12
+ ]
13
+
14
+ [[project.authors]]
15
+ name = "innerkorehq"
16
+
17
+ [project.urls]
18
+ Homepage = "https://github.com/innerkorehq/nse-xbrl"
19
+ Documentation = "https://innerkorehq.github.io/nse-xbrl/"
20
+ Repository = "https://github.com/innerkorehq/nse-xbrl"
21
+ Issues = "https://github.com/innerkorehq/nse-xbrl/issues"
22
+
23
+ [project.optional-dependencies]
24
+ dev = [
25
+ "pytest>=8.0.0",
26
+ "pytest-asyncio>=0.23.0",
27
+ ]
28
+
29
+ [build-system]
30
+ requires = ["uv_build>=0.12.21,<0.13.0"]
31
+ build-backend = "uv_build"
32
+
33
+ [tool.pytest.ini_options]
34
+ asyncio_mode = "auto"
35
+ testpaths = ["tests"]
36
+
37
+ [dependency-groups]
38
+ dev = [
39
+ "myst-parser>=5.1.0",
40
+ "pydata-sphinx-theme>=0.22.0",
41
+ "sphinx>=9.1.0",
42
+ "sphinx-copybutton>=0.5.2",
43
+ "sphinx-design>=0.7.0",
44
+ "sphinxcontrib-mermaid>=2.1.1",
45
+ ]
@@ -0,0 +1,45 @@
1
+ [project]
2
+ name = "nse-xbrl-parser"
3
+ version = "0.1.0"
4
+ description = "Async Python 3.14 library for parsing XBRL Filing Information of NSE & BSE across all taxonomies"
5
+ readme = "README.md"
6
+ authors = [
7
+ { name = "innerkorehq" }
8
+ ]
9
+ requires-python = ">=3.12"
10
+ dependencies = [
11
+ "aiohttp>=3.9.0",
12
+ "lxml>=5.2.0",
13
+ "pydantic>=2.7.0",
14
+ "python-dateutil>=2.9.0",
15
+ ]
16
+
17
+ [project.urls]
18
+ Homepage = "https://github.com/innerkorehq/nse-xbrl"
19
+ Documentation = "https://innerkorehq.github.io/nse-xbrl/"
20
+ Repository = "https://github.com/innerkorehq/nse-xbrl"
21
+ Issues = "https://github.com/innerkorehq/nse-xbrl/issues"
22
+
23
+ [project.optional-dependencies]
24
+ dev = [
25
+ "pytest>=8.0.0",
26
+ "pytest-asyncio>=0.23.0",
27
+ ]
28
+
29
+ [build-system]
30
+ requires = ["uv_build>=0.12.21,<0.13.0"]
31
+ build-backend = "uv_build"
32
+
33
+ [tool.pytest.ini_options]
34
+ asyncio_mode = "auto"
35
+ testpaths = ["tests"]
36
+
37
+ [dependency-groups]
38
+ dev = [
39
+ "myst-parser>=5.1.0",
40
+ "pydata-sphinx-theme>=0.22.0",
41
+ "sphinx>=9.1.0",
42
+ "sphinx-copybutton>=0.5.2",
43
+ "sphinx-design>=0.7.0",
44
+ "sphinxcontrib-mermaid>=2.1.1",
45
+ ]
@@ -0,0 +1,86 @@
1
+ """
2
+ nse-xbrl
3
+
4
+ Async Python 3.14 library for parsing XBRL Filing Information of NSE & BSE across all taxonomies.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ from pathlib import Path
9
+ from typing import List, Union
10
+
11
+ from .client.nse_client import AsyncNSEClient
12
+ from .core.context import ExplicitMember, PeriodType, XBRLContext
13
+ from .core.models import XBRLFact, XBRLInstance
14
+ from .core.parser import AsyncXBRLParser
15
+ from .core.unit import XBRLUnit
16
+ from .taxonomy.downloader import AsyncTaxonomyDownloader
17
+ from .taxonomy.linkbase import ConceptLabel, TaxonomyLinkbase
18
+ from .taxonomy.registry import TaxonomyInfo, TaxonomyRegistry
19
+ from .taxonomy.schema import SchemaElement, TaxonomySchema
20
+ from .typed.corporate_governance import CorporateGovernanceModel
21
+ from .typed.financial_results import FinancialResultsModel
22
+ from .typed.shareholding import ShareholdingPatternModel
23
+
24
+ __version__ = "0.1.0"
25
+
26
+ _parser = AsyncXBRLParser()
27
+
28
+
29
+ async def parse_xbrl(
30
+ content: Union[str, bytes],
31
+ source_name: str | None = None,
32
+ ) -> XBRLInstance:
33
+ """Parse an XBRL XML instance document asynchronously.
34
+
35
+ Args:
36
+ content: XML string or raw bytes.
37
+ source_name: Optional file or URL name for tracking.
38
+
39
+ Returns:
40
+ XBRLInstance: Universal representation of facts, contexts, and units.
41
+ """
42
+ return await _parser.parse(content, source_name=source_name)
43
+
44
+
45
+ async def parse_file(file_path: Union[str, Path]) -> XBRLInstance:
46
+ """Parse a local XBRL file asynchronously."""
47
+ return await _parser.parse_file(file_path)
48
+
49
+
50
+ async def parse_archive(zip_bytes: bytes) -> List[XBRLInstance]:
51
+ """Parse all XBRL filings within a zip archive asynchronously."""
52
+ return await _parser.parse_zip(zip_bytes)
53
+
54
+
55
+ def parse_xbrl_sync(
56
+ content: Union[str, bytes],
57
+ source_name: str | None = None,
58
+ ) -> XBRLInstance:
59
+ """Synchronous parsing convenience function."""
60
+ return _parser.parse_sync(content, source_name=source_name)
61
+
62
+
63
+ __all__ = [
64
+ "parse_xbrl",
65
+ "parse_file",
66
+ "parse_archive",
67
+ "parse_xbrl_sync",
68
+ "AsyncXBRLParser",
69
+ "XBRLInstance",
70
+ "XBRLFact",
71
+ "XBRLContext",
72
+ "XBRLUnit",
73
+ "PeriodType",
74
+ "ExplicitMember",
75
+ "TaxonomyRegistry",
76
+ "TaxonomyInfo",
77
+ "TaxonomySchema",
78
+ "SchemaElement",
79
+ "TaxonomyLinkbase",
80
+ "ConceptLabel",
81
+ "AsyncTaxonomyDownloader",
82
+ "FinancialResultsModel",
83
+ "ShareholdingPatternModel",
84
+ "CorporateGovernanceModel",
85
+ "AsyncNSEClient",
86
+ ]
@@ -0,0 +1,10 @@
1
+ """
2
+ nse_xbrl_parser.client
3
+
4
+ Async clients for NSE and BSE filings.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ from .nse_client import AsyncNSEClient
9
+
10
+ __all__ = ["AsyncNSEClient"]
@@ -0,0 +1,93 @@
1
+ """
2
+ nse_xbrl_parser.client.nse_client
3
+
4
+ Asynchronous client for interacting with NSE corporate filings and archive downloads.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ import asyncio
9
+ from pathlib import Path
10
+ from typing import Any, Dict, List, Optional, Union
11
+ import aiohttp
12
+
13
+ from ..core.models import XBRLInstance
14
+ from ..core.parser import AsyncXBRLParser
15
+ from ..taxonomy.downloader import AsyncTaxonomyDownloader
16
+ from ..taxonomy.registry import TaxonomyInfo, TaxonomyRegistry
17
+
18
+
19
+ class AsyncNSEClient:
20
+ """Asynchronous client for downloading and parsing NSE XBRL disclosures."""
21
+
22
+ DEFAULT_USER_AGENT = (
23
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
24
+ "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
25
+ )
26
+
27
+ def __init__(
28
+ self,
29
+ cookie_string: Optional[str] = None,
30
+ cache_dir: Optional[Path] = None,
31
+ ) -> None:
32
+ self.cookie_string = cookie_string
33
+ self.parser = AsyncXBRLParser()
34
+ self.registry = TaxonomyRegistry()
35
+ self.downloader = AsyncTaxonomyDownloader(cache_dir=cache_dir)
36
+ self._session: Optional[aiohttp.ClientSession] = None
37
+
38
+ async def _get_session(self) -> aiohttp.ClientSession:
39
+ if self._session is None or self._session.closed:
40
+ headers = {
41
+ "User-Agent": self.DEFAULT_USER_AGENT,
42
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
43
+ "Referer": "https://www.nseindia.com/",
44
+ }
45
+ if self.cookie_string:
46
+ headers["Cookie"] = self.cookie_string
47
+ self._session = aiohttp.ClientSession(headers=headers)
48
+ return self._session
49
+
50
+ async def close(self) -> None:
51
+ """Close client session."""
52
+ if self._session and not self._session.closed:
53
+ await self._session.close()
54
+
55
+ async def __aenter__(self) -> AsyncNSEClient:
56
+ return self
57
+
58
+ async def __aexit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
59
+ await self.close()
60
+
61
+ async def download_bytes(self, url: str) -> bytes:
62
+ """Download raw bytes from URL asynchronously."""
63
+ session = await self._get_session()
64
+ async with session.get(url) as response:
65
+ if response.status != 200:
66
+ raise ConnectionError(f"HTTP GET failed with status {response.status} for {url}")
67
+ return await response.read()
68
+
69
+ async def parse_url(self, url: str) -> XBRLInstance:
70
+ """Download XBRL instance document from URL and parse it."""
71
+ data = await self.download_bytes(url)
72
+ return await self.parser.parse(data, source_name=url)
73
+
74
+ async def parse_url_archive(self, zip_url: str) -> List[XBRLInstance]:
75
+ """Download ZIP archive from URL and parse all contained XBRL filings."""
76
+ data = await self.download_bytes(zip_url)
77
+ return await self.parser.parse_zip(data)
78
+
79
+ async def get_taxonomy_schema(self, taxonomy_id: int):
80
+ """Fetch schema for any of the 58 NSE taxonomies."""
81
+ info = self.registry.get_by_id(taxonomy_id)
82
+ if not info:
83
+ raise KeyError(f"Taxonomy ID {taxonomy_id} not found in registry (1-58)")
84
+ schema, _ = await self.downloader.load_taxonomy_metadata(info)
85
+ return schema
86
+
87
+ async def get_taxonomy_labels(self, taxonomy_id: int):
88
+ """Fetch label dictionary for any of the 58 NSE taxonomies."""
89
+ info = self.registry.get_by_id(taxonomy_id)
90
+ if not info:
91
+ raise KeyError(f"Taxonomy ID {taxonomy_id} not found in registry (1-58)")
92
+ _, linkbase = await self.downloader.load_taxonomy_metadata(info)
93
+ return linkbase
@@ -0,0 +1,21 @@
1
+ """
2
+ nse_xbrl_parser.core
3
+
4
+ Core XBRL models, contexts, units, and asynchronous parser engine.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ from .context import ExplicitMember, PeriodType, XBRLContext
9
+ from .models import XBRLFact, XBRLInstance
10
+ from .parser import AsyncXBRLParser
11
+ from .unit import XBRLUnit
12
+
13
+ __all__ = [
14
+ "ExplicitMember",
15
+ "PeriodType",
16
+ "XBRLContext",
17
+ "XBRLFact",
18
+ "XBRLInstance",
19
+ "XBRLUnit",
20
+ "AsyncXBRLParser",
21
+ ]