Refactoring 03 — Copy-Paste API Client¶
Open messy.py. This module fetches data from five endpoints of a JSON API. Each function is nearly identical — classic copy-paste programming.
The code works. But it has five copies of the same logic, no retry mechanism, a hardcoded base URL, and uses print for error reporting.
Your mission¶
Eliminate the duplication and make this code maintainable. The tests in tests/test_messy.py must pass before and after every change.
Refactoring goals¶
-
DRY it up. Extract the shared logic into a single helper function. Each endpoint function should be a one-liner that calls the helper.
-
Extract configuration. The base URL, timeout, and headers are hardcoded. Move them to module-level constants or a configuration dictionary.
-
Add retry logic. Network requests fail. Add a configurable retry mechanism (e.g., retry up to 3 times with a short delay). The helper function should handle this.
-
Replace print with proper error handling. Use
loggingfor error messages. Raise custom exceptions (or return structured errors) instead of silently returningNone. -
Add type hints and docstrings to all functions.
Stretch goals (optional)¶
- Create an
ApiClientclass that holds configuration and provides methods for each endpoint - Add a simple caching mechanism (e.g., cache results for N seconds)
- Add support for query parameters (e.g.,
get_posts(user_id=1))
Process¶
1. Run tests (baseline)
2. Extract helper function -> tests pass
3. Replace each endpoint function -> tests pass after each one
4. Extract configuration -> tests pass
5. Add retry logic -> add new tests -> all pass
6. Replace print with logging -> tests pass
7. Add type hints and docstrings -> done
What you are practicing¶
- Identifying and eliminating code duplication
- Designing reusable helper functions
- Adding resilience (retries) to network code
- Proper error handling and logging patterns