Improve Flickr scraper compatibility and CI#45
Conversation
|
👋 Hello @glenn-jocher, thank you for submitting a
For more guidance, please refer to our Contributing Guide. Don't hesitate to leave a comment if you have any questions. Thank you for contributing to Ultralytics! 🚀 |
UltralyticsAssistant
left a comment
There was a problem hiding this comment.
🔍 PR Review
Made with ❤️ by Ultralytics Actions
The JSON search refactor, credential resolution, and test coverage look good overall. The main issue is pagination: changing per_page between requests breaks page continuity and can miss results. Also, download failures currently bypass the new CLI error handling and can abort a run with an uncaught exception.
💬 Posted 2 inline comments
| response = flickr.photos.search( | ||
| text=search, # https://www.flickr.com/services/api/flickr.photos.search.html | ||
| extras="url_o", | ||
| per_page=min(500, n - len(urls)), # 1-500 |
There was a problem hiding this comment.
per_page needs to stay constant across paginated requests. Because it currently shrinks as len(urls) grows, page=2 is no longer the continuation of page=1 whenever a page yields duplicates, so later requests can overlap earlier results and skip large parts of the search result set.
Suggested change:
| per_page=min(500, n - len(urls)), # 1-500 | |
| per_page=min(500, n), # 1-500 |
| continue | ||
|
|
||
| if download: | ||
| download_uri(url, dir_path) |
There was a problem hiding this comment.
💡 MEDIUM: download_uri() now raises on HTTP failures, but this call isn't handled here. With --download, a single 404/timeout will escape as an uncaught requests exception because the CLI only catches RuntimeError/ValueError, so one bad image can terminate the whole run with a traceback instead of surfacing a clean scraper error or skipping that photo.
|
Merged! 🎉 Huge thanks to @glenn-jocher for this thoughtful upgrade to the Flickr scraper. As Thomas Edison said, “There’s a way to do it better—find it.” This PR reflects that perfectly: better credential handling, a more robust Flickr API flow, pagination support, clearer error reporting, and the addition of tests and CI all make the scraper more reliable, maintainable, and user-friendly. Really appreciate the care put into both the implementation and documentation here—this is a meaningful improvement for everyone using the project. |
Summary
flickrapi.walk()path by using JSONphotos.search, fixing Python 3.9+getchildren()failures--key/--secretorFLICKR_API_KEY/FLICKR_API_SECRETwhile keeping source constants as a fallback--page, clearer Flickr API error reporting, HTTP download status checks, README updates, tests, and a uv-based CI workflowIssues
Fixes #4
Fixes #5
Fixes #6
Fixes #8
Fixes #9
Helps #25
Tests
python -m compileall -q .uv run --with-requirements requirements.txt --with pytest pytest -qgit diff --checkuv run --with-requirements requirements.txt python flickr_scraper.py --search 'honeybees on flowers' --n 1(expected credential error path)\n\nNote: a full-tree Ruff check still reports a pre-existing docstring issue inutils/clean_images.py; touched files pass the repo Ruff settings.🛠️ PR Summary
Made with ❤️ by Ultralytics Actions
🌟 Summary
🚀 This PR makes the Flickr scraper more reliable and easier to use by improving credential handling, switching to a more compatible Flickr API flow, adding pagination support, and introducing automated tests and CI.
📊 Key Changes
🔐 Improved API credential handling
FLICKR_API_KEYandFLICKR_API_SECRETenvironment variables.--keyand--secretCLI options as overrides.🔄 Reworked Flickr search logic
flickrapi.walk()approach with directphotos.searchJSON responses.📄 Added pagination support
--pageargument lets users continue scraping from later Flickr result pages.📥 Cleaner download behavior
✅ Added automated testing and CI
pyteston Python 3.11.📝 README improvements
1/10through10/10.📦 Dependency update
requeststorequirements.txt.🎯 Purpose & Impact
👍 Easier for users to get started
🛠️ Better compatibility and stability
walk()helps avoid known compatibility issues on newer Python versions.🎯 More predictable scraping for dataset collection
🚨 Clearer failure reporting
🔍 Higher code quality and maintainability
📚 Improved documentation