Add QCEW CSV module, ECEC breakdown, response caching + typed errors

Item 1 — QCEW county/industry detail:
- new bls_client/qcew.py: thin client over the QCEW Open Data CSV service
  (area/industry/size slices; no API key, no quota), with filter_rows helper
- covers the county/industry detail the timeseries API can't reach

Item 2 — ECEC benefit breakdown:
- new series.ecec() builder from the authoritative cm.estimate decode table
- real helpers: wages, total benefits, paid leave, supplemental pay,
  health insurance, retirement & savings, legally required + ecec_dashboard()
- FIX: ecec_total_benefits was CMU1036... (education/health industries only);
  correct all-civilian total benefits is CMU1030000000000D

Item 3 — caching + typed errors:
- bls_client/cache.py FileCache (on-disk, TTL); BLSClient(cache=True),
  queries_used counter (cache hits don't spend quota)
- bls_client/errors.py: BLSError / BLSQuotaError / BLSRequestError; quota
  exhaustion now raises a clear BLSQuotaError instead of a generic RuntimeError

Tests: 119 offline (+24) incl. ECEC goldens, QCEW fixture parse, cache/quota
behavior; live smoke extended to ECEC + QCEW. Helper sweep: 96/96 live.
README: caching/QCEW usage, updated coverage + limitations.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-22 10:38:12 -04:00
parent 881d62cf32
commit 9e2c55c568
14 changed files with 499 additions and 44 deletions

7
tests/fixtures/qcew_dc_sample.csv vendored Normal file
View File

@ -0,0 +1,7 @@
area_fips,own_code,industry_code,agglvl_code,size_code,year,qtr,disclosure_code,annual_avg_estabs,annual_avg_emplvl,total_annual_wages,taxable_annual_wages,annual_contributions,annual_avg_wkly_wage,avg_annual_pay,lq_disclosure_code,lq_annual_avg_estabs,lq_annual_avg_emplvl,lq_total_annual_wages,lq_taxable_annual_wages,lq_annual_contributions,lq_annual_avg_wkly_wage,lq_avg_annual_pay,oty_disclosure_code,oty_annual_avg_estabs_chg,oty_annual_avg_estabs_pct_chg,oty_annual_avg_emplvl_chg,oty_annual_avg_emplvl_pct_chg,oty_total_annual_wages_chg,oty_total_annual_wages_pct_chg,oty_taxable_annual_wages_chg,oty_taxable_annual_wages_pct_chg,oty_annual_contributions_chg,oty_annual_contributions_pct_chg,oty_annual_avg_wkly_wage_chg,oty_annual_avg_wkly_wage_pct_chg,oty_avg_annual_pay_chg,oty_avg_annual_pay_pct_chg
11000,0,10,50,0,2024,A,,52240,759666,93430310874,5400587099,119288884,2365,122989,,1.00,1.00,1.00,1.00,1.00,1.00,1.00,,737,1.4,1912,0.3,4099845160,4.6,-94377645,-1.7,-3132981,-2.6,98,4.3,5101,4.3
11000,1,10,51,0,2024,A,,341,193145,27067241499,0,0,2695,140140,,1.29,13.13,11.09,0.00,0.00,0.85,0.84,,1,0.3,2528,1.3,1098653313,4.2,0,0.0,0,0.0,75,2.9,3905,2.9
11000,2,10,51,0,2024,A,,14,38244,3958604832,16139000,243,1991,103508,,0.04,1.62,1.27,0.52,0.00,0.79,0.79,,0,0.0,733,2.0,15426132,0.4,3893850,31.8,104,74.8,-31,-1.5,-1612,-1.5
11000,3,10,51,0,2024,A,,25,3993,538270989,249180,4736,2592,134804,,0.03,0.06,0.07,0.00,0.01,1.25,1.25,,-1,-3.8,-75,-1.8,7573080,1.4,-94668,-27.5,-1797,-27.5,83,3.3,4331,3.3
11000,5,10,51,0,2024,A,,51860,524284,61866193554,5384198919,119283905,2269,118001,,1.02,0.81,0.77,1.02,1.01,0.96,0.96,,736,1.4,-1275,-0.2,2978192635,5.1,-98176827,-1.8,-3131288,-2.6,114,5.3,5953,5.3
11000,8,10,96,0,2024,A,,380,235382,31564117320,16388180,4979,2579,134097,,0.29,2.14,2.38,0.15,0.01,1.11,1.11,,1,0.3,3186,1.4,1121652525,3.7,3799182,30.2,-1693,-25.4,58,2.3,2990,2.3
1 area_fips own_code industry_code agglvl_code size_code year qtr disclosure_code annual_avg_estabs annual_avg_emplvl total_annual_wages taxable_annual_wages annual_contributions annual_avg_wkly_wage avg_annual_pay lq_disclosure_code lq_annual_avg_estabs lq_annual_avg_emplvl lq_total_annual_wages lq_taxable_annual_wages lq_annual_contributions lq_annual_avg_wkly_wage lq_avg_annual_pay oty_disclosure_code oty_annual_avg_estabs_chg oty_annual_avg_estabs_pct_chg oty_annual_avg_emplvl_chg oty_annual_avg_emplvl_pct_chg oty_total_annual_wages_chg oty_total_annual_wages_pct_chg oty_taxable_annual_wages_chg oty_taxable_annual_wages_pct_chg oty_annual_contributions_chg oty_annual_contributions_pct_chg oty_annual_avg_wkly_wage_chg oty_annual_avg_wkly_wage_pct_chg oty_avg_annual_pay_chg oty_avg_annual_pay_pct_chg
2 11000 0 10 50 0 2024 A 52240 759666 93430310874 5400587099 119288884 2365 122989 1.00 1.00 1.00 1.00 1.00 1.00 1.00 737 1.4 1912 0.3 4099845160 4.6 -94377645 -1.7 -3132981 -2.6 98 4.3 5101 4.3
3 11000 1 10 51 0 2024 A 341 193145 27067241499 0 0 2695 140140 1.29 13.13 11.09 0.00 0.00 0.85 0.84 1 0.3 2528 1.3 1098653313 4.2 0 0.0 0 0.0 75 2.9 3905 2.9
4 11000 2 10 51 0 2024 A 14 38244 3958604832 16139000 243 1991 103508 0.04 1.62 1.27 0.52 0.00 0.79 0.79 0 0.0 733 2.0 15426132 0.4 3893850 31.8 104 74.8 -31 -1.5 -1612 -1.5
5 11000 3 10 51 0 2024 A 25 3993 538270989 249180 4736 2592 134804 0.03 0.06 0.07 0.00 0.01 1.25 1.25 -1 -3.8 -75 -1.8 7573080 1.4 -94668 -27.5 -1797 -27.5 83 3.3 4331 3.3
6 11000 5 10 51 0 2024 A 51860 524284 61866193554 5384198919 119283905 2269 118001 1.02 0.81 0.77 1.02 1.01 0.96 0.96 736 1.4 -1275 -0.2 2978192635 5.1 -98176827 -1.8 -3131288 -2.6 114 5.3 5953 5.3
7 11000 8 10 96 0 2024 A 380 235382 31564117320 16388180 4979 2579 134097 0.29 2.14 2.38 0.15 0.01 1.11 1.11 1 0.3 3186 1.4 1121652525 3.7 3799182 30.2 -1693 -25.4 58 2.3 2990 2.3