Repository navigation
Conversation
Camden migrated from environmentservices.camden.gov.uk (server-rendered HTML tables) to recyclingandrubbishcollections.camden.gov.uk (Next.js SPA with JSON API). Rewrote as pure requests: POST /api/getPropertySearch (postcode lookup to resolve property ID from UPRN) then POST /api/getCollectionDays (pointId + pointType PointAddress, councilId 27). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
Warning Review limit reached
Your plan currently allows 2 reviews/hour. Refill in 29 minutes and 16 seconds. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more review capacity refills, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than trial, open-source, and free plans. In all cases, review capacity refills continuously over time. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughCamden Council's bin collection module transitions from HTML page scraping using BeautifulSoup to calling the council's recycling API. It now defines API credentials, searches for properties by postcode with optional UPRN matching, fetches active service schedules, and returns upcoming collection dates sorted chronologically. ChangesCamden Council API Integration
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
Suggested reviewers
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 #2052 +/- ##
=======================================
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: 2
🤖 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/LondonBoroughCamdenCouncil.py`:
- Around line 64-70: The loop over collection_data currently tolerates
missing/changed payloads by using permissive defaults; instead validate and fail
loudly: check that collection_data contains "activeServices" and that it's a
list, raise a ValueError if not; inside the loop assert each service has a
non-empty "serviceName" (don't default to "Unknown") and that "serviceSchedules"
is present and is a list, and for each schedule assert "currentScheduledDate"
exists and is a parseable date (raise an exception if missing/invalid). Update
the code around collection_data, activeServices, serviceName, serviceSchedules
and currentScheduledDate to perform these explicit validations and raise
descriptive exceptions rather than silently continuing.
- Around line 43-45: The code currently falls back to properties[0]["id"] when
point_id is falsy, which silently returns another address's data if an uprn was
supplied but not matched; instead, in the method where point_id, properties and
uprn are handled (LondonBoroughCamdenCouncil.py, symbols: point_id, properties,
uprn), remove the silent fallback and add an explicit failure: if an uprn was
provided and no matching property was found, raise a clear exception (e.g.,
ValueError) containing the uprn and a descriptive message; keep the existing
behavior of selecting properties[0]["id"] only when no uprn was supplied (if
that is intended), otherwise eliminate the fallback entirely per the review.
🪄 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: 97604f43-d3e4-4bb2-a608-2c808042f937
📒 Files selected for processing (1)
uk_bin_collection/uk_bin_collection/councils/LondonBoroughCamdenCouncil.py
| for service in collection_data.get("activeServices", []): | ||
| bin_type = service.get("serviceName", "Unknown") | ||
|
|
||
| for schedule in service.get("serviceSchedules", []): | ||
| date_str = schedule.get("currentScheduledDate") | ||
| if not date_str: | ||
| continue |
There was a problem hiding this comment.
Avoid silent defaults when parsing activeServices payload fields.
Using permissive defaults (activeServices -> [], serviceName -> "Unknown", silently skipping missing dates) can mask upstream API changes and produce misleading empty/partial output.
Suggested fix
- for service in collection_data.get("activeServices", []):
- bin_type = service.get("serviceName", "Unknown")
+ active_services = collection_data.get("activeServices")
+ if not isinstance(active_services, list):
+ raise ValueError("Unexpected collection response: missing/invalid activeServices")
+
+ for service in active_services:
+ if "serviceName" not in service:
+ raise ValueError("Unexpected collection response: missing serviceName")
+ bin_type = service["serviceName"]Based on learnings: “prefer explicit failures (raise exceptions on unexpected formats) over silent defaults or swallowed errors.”
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| for service in collection_data.get("activeServices", []): | |
| bin_type = service.get("serviceName", "Unknown") | |
| for schedule in service.get("serviceSchedules", []): | |
| date_str = schedule.get("currentScheduledDate") | |
| if not date_str: | |
| continue | |
| active_services = collection_data.get("activeServices") | |
| if not isinstance(active_services, list): | |
| raise ValueError("Unexpected collection response: missing/invalid activeServices") | |
| for service in active_services: | |
| if "serviceName" not in service: | |
| raise ValueError("Unexpected collection response: missing serviceName") | |
| bin_type = service["serviceName"] | |
| for schedule in service.get("serviceSchedules", []): | |
| date_str = schedule.get("currentScheduledDate") | |
| if not date_str: | |
| continue |
🤖 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/LondonBoroughCamdenCouncil.py`
around lines 64 - 70, The loop over collection_data currently tolerates
missing/changed payloads by using permissive defaults; instead validate and fail
loudly: check that collection_data contains "activeServices" and that it's a
list, raise a ValueError if not; inside the loop assert each service has a
non-empty "serviceName" (don't default to "Unknown") and that "serviceSchedules"
is present and is a list, and for each schedule assert "currentScheduledDate"
exists and is a parseable date (raise an exception if missing/invalid). Update
the code around collection_data, activeServices, serviceName, serviceSchedules
and currentScheduledDate to perform these explicit validations and raise
descriptive exceptions rather than silently continuing.
Summary
environmentservices.camden.gov.uk(server-rendered HTML) torecyclingandrubbishcollections.camden.gov.uk(Next.js SPA with JSON API)service-wrapperdivs which no longer existPOST /api/getPropertySearchwith postcode to resolve property ID from UPRNPOST /api/getCollectionDayswith pointId/pointType/councilId to get schedulesSummary by CodeRabbit