|
| 1 | +from __future__ import annotations |
| 2 | + |
| 3 | +from dataclasses import asdict, dataclass |
| 4 | +from pathlib import Path |
| 5 | +from typing import Iterable |
| 6 | + |
| 7 | + |
| 8 | +def _normalise(value: str) -> str: |
| 9 | + return value.strip().lower() |
| 10 | + |
| 11 | + |
| 12 | +def _slugify(value: str) -> str: |
| 13 | + return "".join(ch for ch in value.lower() if ch.isalnum()) |
| 14 | + |
| 15 | + |
| 16 | +@dataclass(frozen=True, slots=True) |
| 17 | +class DocumentMetadata: |
| 18 | + id: str |
| 19 | + filename: str |
| 20 | + title: str |
| 21 | + description: str | None = None |
| 22 | + |
| 23 | + @property |
| 24 | + def stem(self) -> str: |
| 25 | + return Path(self.filename).stem |
| 26 | + |
| 27 | + |
| 28 | +DOCUMENTS: tuple[DocumentMetadata, ...] = ( |
| 29 | + DocumentMetadata( |
| 30 | + id="fomc_statement", |
| 31 | + filename="01_fomc_statement_2025-09-17.html", |
| 32 | + title="FOMC Statement — September 17, 2025", |
| 33 | + description="Official statement outlining the Federal Reserve's policy decision and rationale.", |
| 34 | + ), |
| 35 | + DocumentMetadata( |
| 36 | + id="implementation_note", |
| 37 | + filename="02_implementation_note_2025-09-17.html", |
| 38 | + title="Implementation Note — September 17, 2025", |
| 39 | + description="Operational guidance on how the policy decision will be implemented across facilities.", |
| 40 | + ), |
| 41 | + DocumentMetadata( |
| 42 | + id="sep_tables_pdf", |
| 43 | + filename="03_sep_tables_2025-09-17.pdf", |
| 44 | + title="Summary of Economic Projections Tables (PDF)", |
| 45 | + description="PDF tables summarising participants' projections for key economic indicators.", |
| 46 | + ), |
| 47 | + DocumentMetadata( |
| 48 | + id="sep_tables_html", |
| 49 | + filename="04_sep_tables_2025-09-17.html", |
| 50 | + title="Summary of Economic Projections Tables (HTML)", |
| 51 | + description="HTML tables summarising participants' projections for key economic indicators.", |
| 52 | + ), |
| 53 | + DocumentMetadata( |
| 54 | + id="press_conference_transcript", |
| 55 | + filename="05_press_conference_transcript_2025-09-17.pdf", |
| 56 | + title="Press Conference Transcript — September 17, 2025", |
| 57 | + description="Chair Powell's press conference transcript following the September 2025 FOMC meeting.", |
| 58 | + ), |
| 59 | + DocumentMetadata( |
| 60 | + id="bls_cpi_august", |
| 61 | + filename="06_bls_cpi_2025-08.html", |
| 62 | + title="BLS Consumer Price Index — August 2025", |
| 63 | + description="Consumer Price Index report providing the latest inflation readings.", |
| 64 | + ), |
| 65 | + DocumentMetadata( |
| 66 | + id="bea_gdp_q2_second_estimate", |
| 67 | + filename="07_bea_gdp_q2_2025_second_estimate.pdf", |
| 68 | + title="BEA GDP Second Estimate — Q2 2025", |
| 69 | + description="Bureau of Economic Analysis second estimate of GDP for the second quarter of 2025.", |
| 70 | + ), |
| 71 | + DocumentMetadata( |
| 72 | + id="monetary_policy_report", |
| 73 | + filename="08_fed_mpr_2025-06.pdf", |
| 74 | + title="Monetary Policy Report — June 2025", |
| 75 | + description="Semiannual Monetary Policy Report submitted to Congress in June 2025.", |
| 76 | + ), |
| 77 | +) |
| 78 | +DOCUMENTS_BY_ID: dict[str, DocumentMetadata] = {doc.id: doc for doc in DOCUMENTS} |
| 79 | + |
| 80 | +DOCUMENTS_BY_FILENAME: dict[str, DocumentMetadata] = {_normalise(doc.filename): doc for doc in DOCUMENTS} |
| 81 | + |
| 82 | +DOCUMENTS_BY_STEM: dict[str, DocumentMetadata] = {_normalise(doc.stem): doc for doc in DOCUMENTS} |
| 83 | + |
| 84 | +DOCUMENTS_BY_SLUG: dict[str, DocumentMetadata] = {} |
| 85 | +for document in DOCUMENTS: |
| 86 | + for candidate in { |
| 87 | + document.id, |
| 88 | + document.filename, |
| 89 | + document.stem, |
| 90 | + document.title, |
| 91 | + document.description or "", |
| 92 | + }: |
| 93 | + if candidate: |
| 94 | + DOCUMENTS_BY_SLUG.setdefault(_slugify(candidate), document) |
| 95 | + |
| 96 | + |
| 97 | +def as_dicts(documents: Iterable[DocumentMetadata]) -> list[dict[str, str | None]]: |
| 98 | + return [asdict(document) for document in documents] |
0 commit comments