Skip to content

Conversation

@sylvesterdamgaard
Copy link
Contributor

Summary

Fixes critical parsing issues where API response format changes from Geocodio broke field data parsing. The API migrated from flat to nested structures for census, ACS, and school district fields, and renamed several census field names, which would have caused breaking changes for existing users.

Changes

Nested Field Parsing

  • Census data: Now supports both census: {2010: {...}, 2020: {...}} (nested) and census2010: {...} (flat) formats
  • ACS data: Handles both acs: {demographics: {...}} (nested) and acs-demographics: {...} (flat) formats
  • School districts: Parses both school_districts: {elementary: {...}} (nested dict) and school: [...] (flat list) formats

Backward Compatibility

  • Maps new census field names to legacy names:
    • block_codeblock
    • block_groupblockgroup
    • tract_codetract
  • Existing code using fields.census2020.block continues to work without changes

Future-Proofing

  • Dynamic census years: Replaced 31 hardcoded census fields with dynamic __getattr__ - supports census2031+ automatically
  • Congressional districts: cd120, cd121+ work automatically without code changes
  • Extras field: Unknown API fields automatically captured in fields.extras

Model Updates

  • Updated ZIP4Data with complete field definitions (record_type, carrier_route, plus4, zip9, etc.)
  • Updated FFIECData with comprehensive FFIEC CRA/HMDA fields
  • Updated SchoolDistrict with new fields (lea_code, grade_low, grade_high)

Test Plan

Unit Tests

  • All 50 existing unit tests pass
  • Census data parsing with nested structure
  • Census data parsing with flat structure
  • ACS data parsing (simple and nested formats)
  • School districts parsing (dict and list formats)
  • Backward compatibility for legacy field names

Manual Testing with Real API

  • Basic geocoding
  • Census fields (nested parsing)
  • Multiple census years (2010, 2020, 2024)
  • ACS demographics (nested format)
  • ACS economics
  • ZIP+4 data
  • School districts (nested parsing)
  • All fields combined
  • Extras field (future-proofing)
  • Backward compatibility verification: Old field names (block, blockgroup, tract) correctly map to new values

Test Coverage

src/geocodio/client.py    66% coverage (+23% from fixes)
src/geocodio/models.py    99% coverage
Total:                    84% coverage

Breaking Changes

None - This is a backward-compatible fix. Existing code continues to work without modifications.

Related Issues

Fixes #15 (Additional "Fields" not returning School District data)
Fixes #16 (PR to fix API Missing Responses)
Closes #14 (Fields not returning any additional data - nested census/ACS)
Closes #17 (School districts parsing issues)

API changed response format from flat to nested structure for several fields:
- Census: census2010: {...} → census: {2010: {...}}
- ACS: acs-demographics: {...} → acs: {demographics: {...}}
- School districts: school: [...] → school_districts: {elementary: {...}}

Additionally, census field names changed (block → block_code, etc.) which
would break existing code accessing the old field names.

Changes:
- Add nested census parsing with dynamic year support (census2020-census2099+)
- Add nested ACS parsing supporting both simple and metric-specific formats
- Add nested school districts parsing (dict and list formats)
- Map new census field names to legacy names for backward compatibility
- Update ZIP4Data and FFIECData models with complete field definitions
- Remove hardcoded census year fields, use dynamic __getattr__ instead

Backward compatibility ensured:
- fields.census2020.block still works (maps to block_code)
- fields.census2020.blockgroup still works (maps to block_group)
- fields.census2020.tract still works (maps to tract_code)

Future-proof:
- census2031+ years work automatically without code changes
- cd120+ congressional districts work automatically
- Unknown API fields captured in extras dict

Fixes #15
Fixes #16
Closes #14
Closes #17
The test was checking for non-existent fields:
- zip4.zip4 → zip4.plus4
- zip4.delivery_point → zip4.city_delivery

Also added validation for zip9 and valid_delivery_area fields
to match the actual API response structure.

Verified with real API - test now passes.
@sylvesterdamgaard sylvesterdamgaard merged commit 939c0be into main Nov 19, 2025
1 check passed
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.

Additional "Fields" not returning School District data PR to fix API Missing Responses

3 participants