Skip to content

fix(storage): download_filings(filings=) downloads only the requested filings (GH #1608) - #1610

Merged
dgunning merged 1 commit into
mainfrom
fix/1608-download-filings-feeds
Oct 18, 2026
Merged

dgunning merged 1 commit into
mainfrom
fix/1608-download-filings-feeds

Conversation

@dgunning

Copy link
Copy Markdown
Owner

What this changes

download_filings(filings=...) downloads only the requested filings. It used to download SEC's daily feed file for every business day between the first and last filing date and filter only when saving: 1,298 feed files for Snowflake's six 10-Ks. Now:

  • source="submission" (default): each filing's full submission file, the same file Filing.sgml() fetches from SEC, stored at <dir>/<YYYYMMDD>/<accession>.nc(.gz) where the local readers look first.
  • source="feed": feed files, but only the days that hold a requested filing. Each filing's own date is tried first; a filing not there is looked for in the adjacent days, nearest first, because a feed file is keyed by dissemination date (edgartools-a3ej). The issue's suggested fix (skip every day that isn't a filing date) would have dropped those filings without a warning.
  • Filings already stored are skipped. Before, an existing date folder skipped every filing on that date, so a second call with other filings on a shared date downloaded nothing.
  • Filings.download() passes overwrite_existing=False (it passed True only to get past that folder skip) and takes source.
  • filing_date together with filings= narrows the filings to that range.

Fixes #1608

For the reviewer

  • The default for filings= changes from feed files to per-filing submission files. Filings land in the same folders, and the SGML parser detects <SEC-DOCUMENT> vs <SUBMISSION> from content, so readers are unaffected. It's what the docstring already promised, so this is titled a fix, with no upgrade-guide entry.
  • The local-storage guide's table still says "Daily Filings ~100-500 MB". I measured download sizes, not stored size, so I left it.

Verification

  • Ground truth: sizes from SEC: the 2026-03-20 feed file is 2,892,246,544 bytes; Snowflake's 10-K filed that day (0001640147-26-000008) is 17,816,574 bytes. Live run: download_filings(filings=...) stored it as a 2.4 MB .nc.gz, and reading it back with no network gives period of report 2026-01-31 and primary document snow-20260131.htm. The six Snowflake 10-K accessions in the test come from SEC's submissions JSON for CIK 1640147.
  • Regression test: tests/issues/regression/test_issue_1608.py, 11 offline tests (feed listing, feed download and submission request stubbed); 10 fail on main. Against the same stubbed listing, main downloads 1,298 feed files for the six 10-Ks; this branch downloads 6. Covers the next-day feed case (0000950129-95-001652 from a3ej), a shared date already stored, a 404 (reported, the rest continue), and reading a stored Apple 10-K submission (0000320193-24-000123) through Filing.sgml() with the network blocked.
  • Silence check: an unknown source raises ValidationError; filings SEC doesn't have are logged by accession number.
  • Docs: docs/guides/local-storage.md "Filtering Downloads" describes both sources with the measured sizes.
  • Changelog: changelog.d/1608.fixed.md
  • tests/storage + a3ej + new tests: 174 passed, 4 skipped. hatch run test-fast: 42,548 passed, 1 failed (the raw-ValueError ratchet on the new source check, since changed to ValidationError; ratchet and new tests then pass). Regression provenance OK. Lint: no new findings.

AI assistance

  • Assisted. Tool and model: Claude Code, Claude Opus 5.5

🤖 Generated with Claude Code

… filings (GH #1608)

With filings= and no filing_date, download_filings() turned the filings into
one min:max date range and downloaded every daily feed file in it. The only
use of the requested accessions before downloading was a skip nested inside
`if not date_filtered_filings.empty`, so a date with no requested filing was
never skipped. Snowflake's six 10-Ks (2021-03-31 to 2026-03-20) cost 1,298
feed files against a stubbed quarterly listing, to keep 6 filings.

Two more defects on the same path:
- An existing date folder was skipped before the requested filings were
  checked, so a second call with other filings on a shared date downloaded
  nothing. The "already stored" check under it only ran with
  overwrite_existing=True, which is why Filings.download() passed True.
- Even on the right dates, a filing cost its day's whole feed file:
  2,892,246,544 bytes for 2026-03-20 against 17,816,574 for Snowflake's 10-K
  submission (sizes from SEC).

download_filings is split into three paths:
- dates only: unchanged, every feed file in the range.
- filings=, source='submission' (default): each filing's full submission
  .txt, the file Filing.sgml() fetches from SEC, stored at
  <dir>/<YYYYMMDD of filing date>/<accession>.nc(.gz), where the local
  readers look first. The SGML parser detects the format from content, so a
  <SEC-DOCUMENT> file reads like a <SUBMISSION> feed bundle. A 404 is
  reported and the rest continue.
- filings=, source='feed': only feed days holding a pending filing. A feed
  file is keyed by dissemination date, which can differ from the filing date
  (edgartools-a3ej), so the filing date is tried first and only filings still
  missing move to adjacent days, nearest first, within the read side's
  4-day window. The issue's suggested fix (skip any feed day that is not a
  requested filing date) would have lost those filings silently.

Filings already stored under data_directory, in their filing-date folder or
an adjacent one, are skipped unless overwrite_existing. filing_date with
filings= now narrows the filings to that range. Filings.download() passes
overwrite_existing=False and gains source.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dgunning
dgunning merged commit afa474a into main Oct 18, 2026
11 checks passed
@dgunning
dgunning deleted the fix/1608-download-filings-feeds branch October 18, 2026 18:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

download_filings(filings=...) downloads every daily feed file between the earliest and latest filing dates, and only the save step is filtered

1 participant