fix: ZIP rep lookup — correct TIGERweb field names for 119th Congress
Actual API fields are STATE (not STATEFP) and CD119 (not CD119FP). GEOID primary path works for regular districts; fallback now uses STATE + CD\d+ pattern confirmed against live TIGERweb responses. Authored by: Jack Levy
This commit is contained in:
@@ -94,9 +94,8 @@ async def get_members_by_zip(zip_code: str, db: AsyncSession = Depends(get_db)):
|
|||||||
continue
|
continue
|
||||||
attrs = item.get("attributes", {})
|
attrs = item.get("attributes", {})
|
||||||
|
|
||||||
# GEOID / GEOID20 — 2-char state FIPS + 2-char district (e.g. "0618" = CA-18)
|
# Primary: GEOID = 2-char state FIPS + 2-char district (e.g. "0630" = CA-30)
|
||||||
# 119th Congress layers use GEOID20 (2020 Census vintage)
|
geoid = str(attrs.get("GEOID") or "").strip()
|
||||||
geoid = str(attrs.get("GEOID") or attrs.get("GEOID20") or "").strip()
|
|
||||||
if len(geoid) == 4 and geoid.isdigit():
|
if len(geoid) == 4 and geoid.isdigit():
|
||||||
state_fips = geoid[:2]
|
state_fips = geoid[:2]
|
||||||
district_fips = geoid[2:]
|
district_fips = geoid[2:]
|
||||||
@@ -105,12 +104,12 @@ async def get_members_by_zip(zip_code: str, db: AsyncSession = Depends(get_db)):
|
|||||||
if state_code:
|
if state_code:
|
||||||
break
|
break
|
||||||
|
|
||||||
# Fallback: explicit field names (e.g. CD119FP + STATEFP20)
|
# Fallback: STATE + CD{session} fields (e.g. STATE="06", CD119="30")
|
||||||
cd_field = next((k for k in attrs if re.match(r"CD\d+FP$", k)), None)
|
state_val = attrs.get("STATE")
|
||||||
state_field = next((k for k in attrs if "STATEFP" in k.upper()), None)
|
cd_field = next((k for k in attrs if re.match(r"CD\d+$", k)), None)
|
||||||
if cd_field and state_field:
|
if state_val and cd_field:
|
||||||
try:
|
try:
|
||||||
state_fips = str(attrs[state_field]).zfill(2)
|
state_fips = str(state_val).zfill(2)
|
||||||
district_fips = str(attrs[cd_field]).zfill(2)
|
district_fips = str(attrs[cd_field]).zfill(2)
|
||||||
state_code = _FIPS_TO_STATE.get(state_fips)
|
state_code = _FIPS_TO_STATE.get(state_fips)
|
||||||
district_num = str(int(district_fips)) if district_fips.strip("0") else None
|
district_num = str(int(district_fips)) if district_fips.strip("0") else None
|
||||||
@@ -119,11 +118,6 @@ async def get_members_by_zip(zip_code: str, db: AsyncSession = Depends(get_db)):
|
|||||||
except (ValueError, TypeError):
|
except (ValueError, TypeError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
logger.debug(
|
|
||||||
"ZIP %s: could not parse layer %r — attrs: %s",
|
|
||||||
zip_code, item.get("layerName"), list(attrs.keys()),
|
|
||||||
)
|
|
||||||
|
|
||||||
if not state_code:
|
if not state_code:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"ZIP %s: no CD found. Layers: %s",
|
"ZIP %s: no CD found. Layers: %s",
|
||||||
|
|||||||
Reference in New Issue
Block a user