Add network fallback helper functions (#50 Task 2.4)#60
Conversation
Consolidates duplicate try-except fallback patterns into reusable helpers: - open_dataset_with_fallback(): FRF -> CHL server fallback pattern - open_dataset_with_retry(): Retry loop with configurable attempts/delay Refactored: - getWaveGaugeLoc(): Now uses open_dataset_with_fallback() - getModelField(): Now uses open_dataset_with_retry() (was 15-iteration loop) Added 10 tests for helper functions covering: - Primary/fallback URL handling - IOError and OSError handling - Retry logic and config defaults - Error message printing Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR introduces reusable network-open helper functions in murgtools.getdata.getDataFRF to centralize the project’s common “fallback URL” and “retry open” patterns, and then refactors existing data-access methods to use them.
Changes:
- Added
open_dataset_with_fallback()(primary URL → fallback URL) andopen_dataset_with_retry()(retry loop with delay/config default). - Refactored
getWaveGaugeLoc()to use fallback helper and raise when both URLs fail. - Refactored
getModelField()to use retry helper and raise a clearerRuntimeErrorwhen retries are exhausted; added tests for both helpers.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
murgtools/getdata/getDataFRF.py |
Adds new dataset-open helpers and refactors callers (getWaveGaugeLoc, getModelField) to reduce duplicated network retry/fallback logic. |
tests/test_getDataFRF.py |
Adds unit tests covering success, fallback, retry exhaustion, and config-default behavior for the new helpers. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| Attempts to open a NetCDF dataset, retrying on IOError up to max_retries | ||
| times with a delay between attempts. |
| if ncfile is None: | ||
| raise IOError(f"Could not open dataset for gauge {gaugenumber}") |
Refinements based on code review: - open_dataset_with_fallback(): Add raise_on_failure parameter for Pythonic exception handling. Default returns None, but callers can opt-in to exceptions. - open_dataset_with_retry(): Use logging module instead of print() for proper log levels (WARNING for retries, ERROR for final failure). Store last error for better error messages. - Update getWaveGaugeLoc() to use raise_on_failure=True for cleaner code - Update tests to use caplog fixture for logging assertions - Add test for raise_on_failure behavior - Add test for final failure logging Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
| Attempts to open a NetCDF dataset from the primary URL. If that fails | ||
| with an IOError (network issue, file not found), automatically tries | ||
| the fallback URL. |
| Returns: | ||
| netCDF4.Dataset: The opened dataset. |
| Attempts to open a NetCDF dataset, retrying on IOError up to max_retries | ||
| times with a delay between attempts. Logs progress using the logging module. |
Addresses PR #60 review comments: - Rename parameter from max_retries to max_attempts to clarify that it represents total attempts (not additional retries after first try) - Add input validation requiring max_attempts >= 1 - Update docstring to explain semantics (max_attempts=3 means 3 total tries) - Update all callers and tests to use new parameter name Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Addresses PR #60 review comments: - Document that both IOError and OSError trigger fallback (not just IOError) - Fix return type to show it can return None when raise_on_failure=False Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
@copilot please review the commits and check for clairty and capability |
Reviewed the commits — all reviewer feedback has already been addressed in commits
All 157 tests pass including the 12 new helper-specific tests. |
| try: | ||
| return nc.Dataset(primary_url) | ||
| except (IOError, OSError): | ||
| pass # Fall through to try fallback | ||
|
|
||
| try: | ||
| return nc.Dataset(fallback_url) | ||
| except (IOError, OSError) as e: | ||
| if raise_on_failure: | ||
| raise IOError(f"Failed to open dataset from both {primary_url} and {fallback_url}") from e | ||
| return None |
| except (IOError, OSError) as e: | ||
| last_error = e | ||
| if attempt < max_attempts - 1: | ||
| logging.warning(f"Error reading {url}, attempt {attempt + 1}/{max_attempts}. Retrying...") |
Addresses PR #60 review comments: - open_dataset_with_fallback: Include both primary and fallback error messages when raise_on_failure=True, showing why each URL failed - open_dataset_with_retry: Include exception message in retry warning to help diagnose DNS, timeout, permission issues etc. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Summary
open_dataset_with_fallback()for FRF -> CHL server fallback patternopen_dataset_with_retry()for retry loops with configurable attempts/delaygetWaveGaugeLoc()andgetModelField()to use new helpersChanges
getWaveGaugeLoc()getModelField()Test plan
🤖 Generated with Claude Code