Skip to content

fix: fix UPRN param encoding for SouthamptonCityCouncil#1722

Merged
robbrad merged 2 commits into
robbrad:dec_releasefrom
tico24:maybe-fix-scc
Dec 7, 2025
Merged

fix: fix UPRN param encoding for SouthamptonCityCouncil#1722
robbrad merged 2 commits into
robbrad:dec_releasefrom
tico24:maybe-fix-scc

Conversation

@tico24
Copy link
Copy Markdown
Contributor

@tico24 tico24 commented Nov 17, 2025

I'm hoping this will fix #1719

I have been unable to test locally due to Captcha issues.

Summary by CodeRabbit

  • Bug Fixes
    • Restored reliable Southampton City Council bin collection lookup so collection dates are retrieved consistently.
    • Improved validation to surface a clear error when a council's waste calendar is missing or unreachable.
    • No changes to how collection dates are displayed or sorted for users.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Nov 17, 2025

Walkthrough

Replaced set-like UPRN parameter with a plain string in the request and added explicit regex matching and an error guard when extracting the calendar view to avoid NoneType subscripting.

Changes

Cohort / File(s) Summary
Southampton parser
uk_bin_collection/uk_bin_collection/councils/SouthamptonCityCouncil.py
- Changed request param from {"UPRN": {user_uprn}} to {"UPRN": user_uprn}.
- Added calendar_match = re.search(...) and a guard that raises ValueError if the calendar view isn't found; replaced use of index-based access with calendar_match.group(0).
- Minor variable renames and formatting tweaks; no other logic changes.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Parser as SouthamptonCityCouncil.parse_data
    participant API as Waste Calendar API
    Note over Parser,API: Request UPRN formatting fix
    Parser->>API: POST /calendar {"UPRN": "100060745730"}
    API-->>Parser: HTML response
    Note over Parser: Calendar extraction with regex and guard
    Parser->>Parser: re.search(calendar_pattern, html) -> calendar_match
    alt match found
        Parser->>Parser: use calendar_match.group(0) -> parse events
    else no match
        Parser->>Parser: raise ValueError("Could not find calendar view")
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Single-file change but includes request payload and parsing guard; verify both network parameter and HTML-extraction behavior.
  • Pay attention to:
    • Exact request shape sent to the council endpoint.
    • The regex used for calendar extraction and error message semantics.
    • Any callers or tests that assume previous return/exception behavior.

Possibly related PRs

Poem

🐰 I nibbled code and fixed a string,
Clawed out a bug where None would sting.
I searched the page with careful sight,
Found the calendar — now it’s right.
Hooray for bins and bedtime light! 🥕

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title clearly and specifically describes the main change: fixing UPRN parameter encoding for SouthamptonCityCouncil integration, matching the code modification.
Linked Issues check ✅ Passed Code changes address issue #1719 by modifying UPRN parameter handling and adding validation for calendar view access, potentially resolving the 'NoneType' object error.
Out of Scope Changes check ✅ Passed All changes in SouthamptonCityCouncil.py are directly related to fixing the UPRN parameter encoding and calendar view validation required by issue #1719; no unrelated changes detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@tico24 tico24 changed the title Fix: Correct the construction of the Southampton City Council URL fix: Correct the construction of the Southampton City Council URL Nov 17, 2025
@codecov
Copy link
Copy Markdown

codecov Bot commented Nov 17, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.79%. Comparing base (37c8a80) to head (f2b9310).
⚠️ Report is 97 commits behind head on dec_release.

Additional details and impacted files
@@             Coverage Diff              @@
##           dec_release    #1722   +/-   ##
============================================
  Coverage        86.79%   86.79%           
============================================
  Files                9        9           
  Lines             1136     1136           
============================================
  Hits               986      986           
  Misses             150      150           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
uk_bin_collection/uk_bin_collection/councils/SouthamptonCityCouncil.py (1)

68-70: Add error handling for failed regex match.

While the line 57 fix should resolve the immediate issue, there's no defensive error handling here. If re.search() returns None (e.g., if the council website HTML structure changes), attempting to subscript with [0] will raise the same 'NoneType' object is not subscriptable error reported in issue #1719.

Apply this diff to add proper error handling:

-    calendar_view_only = re.search(
-        r"#calendar1.*?listView", r.text, flags=re.DOTALL
-    )[0]
+    calendar_match = re.search(
+        r"#calendar1.*?listView", r.text, flags=re.DOTALL
+    )
+    if not calendar_match:
+        raise ValueError(
+            "Unable to find calendar view in response. The council website structure may have changed."
+        )
+    calendar_view_only = calendar_match.group(0)
🧹 Nitpick comments (1)
uk_bin_collection/uk_bin_collection/councils/SouthamptonCityCouncil.py (1)

74-82: Consider adding error handling for date parsing.

While the regex pattern on line 37 validates the date format, if the council website changes its date format, the strptime() call on line 78 could raise a ValueError. Consider wrapping the date parsing in a try-except block to provide a more informative error message.

Example:

 for item in results:
-
-    dict_data = {
-        "type": item[0],
-        "collectionDate": datetime.strptime(item[1], "%m/%d/%Y").strftime(
-            "%d/%m/%Y"
-        ),
-    }
-    bindata["bins"].append(dict_data)
+    try:
+        dict_data = {
+            "type": item[0],
+            "collectionDate": datetime.strptime(item[1], "%m/%d/%Y").strftime(
+                "%d/%m/%Y"
+            ),
+        }
+        bindata["bins"].append(dict_data)
+    except ValueError as e:
+        raise ValueError(
+            f"Failed to parse date '{item[1]}' for waste type '{item[0]}': {e}"
+        )
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 37c8a80 and 4344c55.

📒 Files selected for processing (1)
  • uk_bin_collection/uk_bin_collection/councils/SouthamptonCityCouncil.py (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Run Unit Tests (3.12, 1.8.4)
  • GitHub Check: Run Integration Tests (3.12, 1.8.4)
🔇 Additional comments (1)
uk_bin_collection/uk_bin_collection/councils/SouthamptonCityCouncil.py (1)

56-58: Critical fix correctly applied!

The change from {"UPRN": {user_uprn}} to {"UPRN": user_uprn} is the correct fix. The old code was constructing a set ({user_uprn}) instead of passing the string directly, which would have caused the UPRN to be serialized incorrectly in the URL parameters. This prevented the server from returning valid HTML, leading to the downstream 'NoneType' error.

@tico24
Copy link
Copy Markdown
Contributor Author

tico24 commented Nov 17, 2025

I have no idea how to appease this CI. It's a black box.

Signed-off-by: Tim Collins <tim@thecollins.team>

formatting

Signed-off-by: Tim Collins <tim@thecollins.team>

chore: trigger CI for SouthamptonCityCouncil fix
@tico24 tico24 changed the title fix: Correct the construction of the Southampton City Council URL fix: fix UPRN param encoding for SouthamptonCityCouncil Nov 17, 2025
Signed-off-by: Tim Collins <tim@thecollins.team>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
uk_bin_collection/uk_bin_collection/councils/SouthamptonCityCouncil.py (1)

5-5: Consider adding explicit import for re module.

The static analysis tool flags that re may be undefined due to the star import on line 5. While this is a pre-existing issue not introduced by this PR, adding an explicit import re statement would improve code clarity and eliminate the static analysis warning.

Apply this diff to add an explicit import:

 import time
 
 import requests
+import re
 
 from uk_bin_collection.uk_bin_collection.common import *
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8e7fdb4 and f2b9310.

📒 Files selected for processing (1)
  • uk_bin_collection/uk_bin_collection/councils/SouthamptonCityCouncil.py (4 hunks)
🧰 Additional context used
🪛 Ruff (0.14.4)
uk_bin_collection/uk_bin_collection/councils/SouthamptonCityCouncil.py

68-68: re may be undefined, or defined from star imports

(F405)


69-69: re may be undefined, or defined from star imports

(F405)


72-74: Avoid specifying long messages outside the exception class

(TRY003)

🔇 Additional comments (3)
uk_bin_collection/uk_bin_collection/councils/SouthamptonCityCouncil.py (3)

56-58: Critical bug fix: Correct UPRN parameter encoding.

The old code {"UPRN": {user_uprn}} created a set object as the parameter value due to Python's set literal syntax. When requests.get serialized this to a query string, it would produce malformed output that the council website couldn't parse correctly. This was the root cause of issue #1719.

The fix correctly passes the UPRN as a plain string value.


68-75: Good defensive programming: Added error guard for calendar view extraction.

The new code properly checks if the regex search returns None before attempting to access the match result. This prevents the 'NoneType' object is not subscriptable error reported in issue #1719 when the calendar view is not found in the response.

The error message is clear and helps diagnose issues if the council website structure changes.


17-93: Request verification: Confirm fix resolves issue #1719.

The author was unable to test locally due to CAPTCHA issues. Please verify that these changes successfully resolve the setup failure reported in issue #1719 using the example UPRN 100060745730 or similar test data.

The two fixes (UPRN parameter encoding + error guard) should address the root cause, but confirmation with real data is essential.

If you have access to test the integration, you can verify by:

  1. Setting up the Southampton City Council integration with a valid UPRN
  2. Confirming that setup completes without the 'NoneType' object is not subscriptable error
  3. Verifying that bin collection data is retrieved successfully

@robbrad robbrad changed the base branch from master to dec_release December 7, 2025 10:17
@robbrad robbrad merged commit 3672cff into robbrad:dec_release Dec 7, 2025
13 checks 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.

Southampton City Council - Issue/Bug - 'NoneType' object is not subscriptable.

2 participants