1717from os import cpu_count
1818from secsgml2 import parse_sgml_content_into_memory
1919from ..utils .format_accession import format_accession
20- from ..providers .providers import SEC_FILINGS_SGML_BUCKET_ENDPOINT
21- from .datamule_lookup import datamule_lookup
20+ from ..providers .providers import SEC_FILINGS_ARCHIVE_SGML_ENDPOINT
21+ from .archive_lookup import lookup_archive_sgml
2222
2323# Set up logging
2424logging .basicConfig (
3131
3232class Downloader :
3333 def __init__ (self , api_key = None ):
34- self .BASE_URL = SEC_FILINGS_SGML_BUCKET_ENDPOINT
34+ self .BASE_URL = SEC_FILINGS_ARCHIVE_SGML_ENDPOINT
3535 self .CHUNK_SIZE = 2 * 1024 * 1024
3636 self .MAX_CONCURRENT_DOWNLOADS = 10
3737 self .MAX_DECOMPRESSION_WORKERS = cpu_count ()
@@ -222,7 +222,8 @@ async def download_and_process(self, session, url, semaphore, decompression_pool
222222 chunks .append (chunk )
223223
224224 loop = asyncio .get_running_loop ()
225- if content_type == 'application/zstd' :
225+ is_zstd = filename .endswith ('.zst' ) or 'zstd' in content_type
226+ if is_zstd :
226227 logger .debug (f"Processing { filename } as compressed (zstd)" )
227228 success = await loop .run_in_executor (
228229 decompression_pool ,
@@ -286,20 +287,36 @@ async def process_batch(self, urls, output_dir, keep_document_types=[], max_batc
286287 finally :
287288 tar_manager .close_all ()
288289
289- def download (self , accession_numbers , output_dir = "downloads" , keep_document_types = [],
290- max_batch_size = 1024 * 1024 * 1024 ):
290+ def _url_from_archive_record (self , record ):
291+ filing_date = record .get ('filing_date' ) or record .get ('filingDate' )
292+ accession = record .get ('accession' )
293+ if filing_date is None or accession is None :
294+ raise ValueError ("Archive lookup record must include filing_date and accession" )
295+
296+ accession = format_accession (accession , 'no-dash' )
297+ return f"{ self .BASE_URL } { filing_date } /{ accession } .sgml.zst"
298+
299+ def download (self , accession_numbers = None , output_dir = "downloads" , keep_document_types = [],
300+ max_batch_size = 1024 * 1024 * 1024 , archive_records = None ):
291301 if self .api_key is None :
292302 raise ValueError ("No API key found. Please set DATAMULE_API_KEY environment variable or provide api_key in constructor" )
293303
294- logger .debug (f"Generating URLs for { len (accession_numbers )} filings..." )
304+ if archive_records is None :
305+ if not accession_numbers :
306+ logger .warning ("No submissions found matching the criteria" )
307+ return
308+ archive_records = lookup_archive_sgml (
309+ accession = accession_numbers ,
310+ api_key = self .api_key ,
311+ quiet = True ,
312+ )
313+
314+ logger .debug (f"Generating URLs for { len (archive_records )} filings..." )
295315
296- urls = []
297- for accession in accession_numbers :
298- url = f"{ self .BASE_URL } { format_accession (accession ,'no-dash' )} .sgml"
299- urls .append (url )
316+ urls = [self ._url_from_archive_record (record ) for record in archive_records ]
300317
301318 # Deduplicate URLs
302- urls = list (set (urls ))
319+ urls = list (dict . fromkeys (urls ))
303320
304321 if not urls :
305322 logger .warning ("No submissions found matching the criteria" )
@@ -331,15 +348,24 @@ def download(cik=None, ticker=None, submission_type=None, filing_date=None,
331348 """
332349 Download SEC filings from DataMule.
333350
334- If accession_numbers is provided, downloads those directly.
335- Otherwise, queries datamule_lookup with the provided filters to get accession numbers .
351+ If accession_numbers is provided, resolves those archive records directly.
352+ Otherwise, queries the v3 archive lookup with the provided filters.
336353 """
337354
338355 downloader = Downloader (api_key = api_key )
339356
340- # Get accession numbers if not provided
341- if accession_numbers is None :
342- accession_numbers = datamule_lookup (
357+ # Get archive coordinates if not provided
358+ if accession_numbers is not None :
359+ if not accession_numbers :
360+ logger .warning ("No submissions found matching the criteria" )
361+ return
362+ archive_records = lookup_archive_sgml (
363+ accession = accession_numbers ,
364+ quiet = quiet ,
365+ api_key = api_key ,
366+ )
367+ else :
368+ archive_records = lookup_archive_sgml (
343369 cik = cik ,
344370 ticker = ticker ,
345371 submission_type = submission_type ,
@@ -354,18 +380,17 @@ def download(cik=None, ticker=None, submission_type=None, filing_date=None,
354380 skip_accession_numbers = skip_accession_numbers ,
355381 quiet = quiet ,
356382 api_key = api_key ,
357- provider = 'datamule-sgml' ,
358383 ** kwargs
359384 )
360385
361386
362- if not accession_numbers :
363- logger .warning ("No submissions found matching the criteria" )
364- return
387+ if not archive_records :
388+ logger .warning ("No submissions found matching the criteria" )
389+ return
365390
366391 # Download the filings
367392 downloader .download (
368- accession_numbers = accession_numbers ,
393+ archive_records = archive_records ,
369394 output_dir = output_dir ,
370395 keep_document_types = keep_document_types ,
371396 max_batch_size = max_batch_size
0 commit comments