feat: add postcode lookup for lincoln council#2068
Conversation
Users can provide either UPRN or postcode + house number. UPRN takes priority when provided (backward compatible). When no UPRN given, sends empty chooseaddress to AchieveForms API which returns all addresses for the postcode with bin data. Matches address by house number in the display field. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughLincolnCouncil address lookup is enhanced to support PAON (house_number) as a fallback when UPRN is unavailable. A new PAON-matching helper method is introduced, parse_data is refactored to zero-pad UPRN values and conditionally populate API requests, and bin results are filtered to the resolved target address. Test configuration is updated to reflect the optional UPRN requirement. ChangesLincoln Council address lookup with PAON fallback
Sequence Diagram(s)sequenceDiagram
participant Input as Input: UPRN or PAON
participant ParseData as parse_data
participant API as API Request
participant Match as _match_by_paon
participant Filter as Bin Filter
Input ->> ParseData: user_uprn or paon
ParseData ->> ParseData: Zero-pad user_uprn if present
ParseData ->> API: chooseaddress: user_uprn or ''
API -->> ParseData: rows_data
alt user_uprn provided
ParseData ->> Filter: target_uprn = user_uprn
else multiple rows and paon provided
ParseData ->> Match: Match paon against display fields
Match -->> ParseData: matched UPRN
ParseData ->> Filter: target_uprn = matched UPRN
end
Filter ->> Filter: Generate bins only for target_uprn rows
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #2068 +/- ##
=======================================
Coverage 86.67% 86.67%
=======================================
Files 9 9
Lines 1141 1141
=======================================
Hits 989 989
Misses 152 152 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@uk_bin_collection/uk_bin_collection/councils/LincolnCouncil.py`:
- Around line 71-78: The current resolve logic silently falls back to the first
address when PAON resolution is ambiguous or fails; change it to fail explicitly
instead: in the method that sets target_uprn (using variables user_uprn,
user_paon, rows_data and calling _match_by_paon), detect when rows_data has
multiple entries and _match_by_paon returns no unique match (or when user_paon
is provided but ambiguous) and raise a clear exception (e.g., ValueError or a
custom NotFound/AmbiguousMatch error) instead of using next(iter(rows_data));
also update the other occurrences where the code silently picks
next(iter(rows_data)) (including the spots that call the same resolution flow
referenced by _match_by_paon) to follow the same explicit-failure behavior so
callers can handle/return an error rather than returning potentially-wrong bin
data.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 7aed1461-28d3-4f47-8f14-49418dcc7d49
📒 Files selected for processing (2)
uk_bin_collection/tests/input.jsonuk_bin_collection/uk_bin_collection/councils/LincolnCouncil.py
| # Resolve which UPRN to use | ||
| if user_uprn: | ||
| target_uprn = user_uprn | ||
| elif user_paon and len(rows_data) > 1: | ||
| target_uprn = self._match_by_paon(rows_data, user_paon) | ||
| else: | ||
| target_uprn = next(iter(rows_data)) | ||
|
|
There was a problem hiding this comment.
Avoid silent first-address fallback for ambiguous/no-match cases.
Lines 74-78 and Line 124 silently select the first address when PAON cannot be deterministically resolved. That can return bin data for the wrong property; fail explicitly instead.
🔧 Safer resolution flow
- if user_uprn:
- target_uprn = user_uprn
- elif user_paon and len(rows_data) > 1:
- target_uprn = self._match_by_paon(rows_data, user_paon)
- else:
- target_uprn = next(iter(rows_data))
+ if not rows_data:
+ raise LookupError("No address rows returned for the provided postcode")
+
+ if user_uprn:
+ target_uprn = user_uprn
+ if target_uprn not in rows_data:
+ raise LookupError(f"UPRN {target_uprn} was not returned by Lincoln API")
+ elif user_paon and len(rows_data) > 1:
+ target_uprn = self._match_by_paon(rows_data, user_paon)
+ if target_uprn is None:
+ raise LookupError(f"No address matched PAON '{user_paon}'")
+ elif len(rows_data) == 1:
+ target_uprn = next(iter(rows_data))
+ else:
+ raise LookupError("Multiple addresses returned; provide UPRN or exact house_number")
@@
- return next(iter(rows_data))
+ return NoneBased on learnings: In uk_bin_collection/**/*.py, prefer explicit failures over silent defaults when formats/matches are unexpected.
Also applies to: 86-87, 124-124
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@uk_bin_collection/uk_bin_collection/councils/LincolnCouncil.py` around lines
71 - 78, The current resolve logic silently falls back to the first address when
PAON resolution is ambiguous or fails; change it to fail explicitly instead: in
the method that sets target_uprn (using variables user_uprn, user_paon,
rows_data and calling _match_by_paon), detect when rows_data has multiple
entries and _match_by_paon returns no unique match (or when user_paon is
provided but ambiguous) and raise a clear exception (e.g., ValueError or a
custom NotFound/AmbiguousMatch error) instead of using next(iter(rows_data));
also update the other occurrences where the code silently picks
next(iter(rows_data)) (including the spots that call the same resolution flow
referenced by _match_by_paon) to follow the same explicit-failure behavior so
callers can handle/return an error rather than returning potentially-wrong bin
data.
Summary
chooseaddressto AchieveForms API - returns all addresses for the postcode along with bin data in one calldisplayfieldTesting
LN1 3AE+ UPRN000235056871✅LN1 3AE+ paon2✅Summary by CodeRabbit