feat(serve): load taxonomy packages and page long networks - #69
Merged
Merged
Conversation
`load_filing` refused a taxonomy published on its own — a zip or directory of schemas and linkbases with no report — with "No inline document or XBRL instance found", even though every tool works on its DTS once Arelle is pointed at the right schema. - A package with no report now loads from an entry point: the first one `META-INF/taxonomyPackage.xml` lists, resolved into the package through its catalog (FASB's US GAAP and SRT packages open with `entire/…-entryPoint-all`), or, with no manifest (GASB's exposure drafts), the one schema nothing else in the package imports. Several root schemas and no manifest asks for one. - `load_filing` takes `entry_point` to load another, by its path in the package, file name or name. - The receipt and `describe_filing` carry a `taxonomy` block naming the entry point loaded and the others on offer, and the next steps point at resolve_element, disclosures, statement and information_block. - An elements-only entry point has no networks for the tools to read; it is refused as such rather than as "not XBRL". - A `.zip` URL is downloaded and loaded as a local package, so a published taxonomy loads by its URL (`https://xbrl.fasb.org/us-gaap/2026/us-gaap-2026.zip`).
A taxonomy's own networks outrun the 400-row cap: US GAAP's classified balance sheet walks to 691 rows, and `statement` stopped in current liabilities with no way to reach Liabilities, StockholdersEquity or LiabilitiesAndStockholdersEquity. - `statement` and `information_block` take `offset`. A truncated response returns `next_offset`; passing it back returns the next page, and the pages join into the unpaged rows with their depths intact. - A later page carries `ancestors`, the headers above its first row, so a page that opens deep in the tree says what it sits under. - `information_block` returns the section's axes, calculation and text with the first page only; later pages carry rows and their columns. - An offset past the end is refused with the row count.
Tool descriptions ship in every client's prompt, so every xbrlkit user pays for them. The taxonomy loading detail stays in serve/README.md.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
load_filingrefused a taxonomy published on its own (a zip of schemas and linkbases with no report), even though every tool reads its DTS once Arelle is pointed at the right schema. A package with no report now loads from an entry point, by path or by URL. Once loaded, a taxonomy's networks outran the 400-row cap with no way to reach the rest, sostatementandinformation_blocknow page.Taxonomy support is a load format, not a new lane: no new tools, one optional parameter on
load_filing, and reports load exactly as before.Changes
serve/session.py(loading)META-INF/taxonomyPackage.xmllists, resolved into the package through its catalog'srewriteURI; or, with no manifest, the one schema nothing else in the package imports. With no manifest and several root schemas, the load asks for one.FilingSession.loadtakesentry_pointto load another, matched by path in the package, file name, stem or manifest name. An ambiguous or unknown name is refused with the candidates listed.entry_pointon a source that is not a package is refused..zipURL is downloaded and loaded as a local package. This is also the path a report zip given by URL now takes, the same onelei:/ filings.xbrl.org loads already use._find_load_targetreturnsNoneinstead of raising when a package holds no report.serve/tools.py(surface)describe_filingcarry ataxonomyblock: the entry point loaded and the others on offer. The next steps for a taxonomy point atresolve_element,disclosures,statementandinformation_block.statementandinformation_blocktakeoffset. A truncated response returnsnext_offset; the pages join into the unpaged rows with depths intact. A later page carriesancestors(the headers above its first row).information_blockreturns axes, calculation and text with the first page only. An offset past the end is refused with the row count.serve/server.py+serve/README.mdentry_pointonload_filing,offsetonstatementandinformation_block. The tool text grows by one sentence each, since it ships in every client's prompt; the detail lives inserve/README.md.Output Impact
BROADER COVERAGE: taxonomy packages that previously failed to load now load (FASB US GAAP / SRT, and manifest-less packages such as GASB's 2026 taxonomy exposure draft). Holon, TAVI and model output are unchanged;
serialize/is untouched.MCP surface changes are additive: new optional parameters and a
taxonomykey present only on taxonomy loads. The CLI is unchanged;xbrlkit serve/viewtake a taxonomy zip as a source but have no--entry-pointflag. The robosystems information-block operation callsinformation_blockwith keyword arguments, so the newoffsetparameter does not affect it.Testing
just test-all(via the commit hook): ruff, format, basedpyright clean; 544 passed, 2 skipped.New tests (hermetic, Arelle mocked at
_parse): root-schema detection that ignores linkbase back-references, several roots asking for one, manifest order with a catalog-rewritten URL and a relative href, entry-point matching and its errors, the receipt block, the elements-only refusal, a zip by URL,entry_pointrefused off-package, and paging that joins back into the unpaged rows for both tools.Real loads through the branch code (no report, so no accession numbers):
gasb-exposure-2026.zip(no manifest)gasb-exposure-2026.xsdus-gaap-2025.zipentire/us-gaap-entryPoint-all-2025.xsd, 10 others listedus-gaap-2025.zip,entry_point="us-gaap-entryPoint-std-2025"entire/us-gaap-entryPoint-std-2025.xsdhttps://xbrl.fasb.org/us-gaap/2026/us-gaap-2026.zipentire/us-gaap-entryPoint-all-2026.xsdhttps://xbrl.fasb.org/srt/2026/srt-2026.zipentire/srt-entryPoint-all-2026.xsdUS GAAP 2025 network counts were checked against the raw linkbases the entry point reaches: 111 FASB presentation roles (+7 from the SEC taxonomies it imports), 65 calculation roles, 397 FASB definition roles (+11 SEC). The classified balance sheet pages to 691 rows over two calls;
Liabilities,StockholdersEquityandLiabilitiesAndStockholdersEquity, previously unreachable past the cap, sit at rows 535, 594 and 690. The Leases (Topic 842) block pages to 771 rows over two calls.Known and left alone:
resolve_elementranking has no fact counts to lean on in a taxonomy ("revenue" on US GAAP does not rankus-gaap:Revenuesfirst), and GASB's statements are not classified as statements. Both wait for real demand.