Skip to content

Fix/docs build#142

Merged
singjc merged 3 commits intoOpenMS:mainfrom
singjc:fix/docs_build
Jan 17, 2026
Merged

Fix/docs build#142
singjc merged 3 commits intoOpenMS:mainfrom
singjc:fix/docs_build

Conversation

@singjc
Copy link
Collaborator

@singjc singjc commented Jan 17, 2026

Fix issues with docs build. Downloads with zenodo links now throws a 403 error, either due to reduce rate limits from excessive requests when building the notebooks.
We will now first try download from the github repo itself since it already has the test files, and then try zenodo as a backup if it also fails.

Summary by CodeRabbit

  • New Features

    • Documentation gallery scripts now feature improved data download reliability through automatic fallback to multiple data sources, ensuring robust access to example datasets
  • Chores

    • GitHub Actions workflows optimized to automatically cancel redundant concurrent runs on the same branch or pull request, streamlining CI/CD execution

✏️ Tip: You can customize this high-level summary in your review settings.

Copilot AI review requested due to automatic review settings January 17, 2026 15:55
@singjc singjc enabled auto-merge January 17, 2026 15:55
@coderabbitai
Copy link

coderabbitai bot commented Jan 17, 2026

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Multiple GitHub Actions workflows now include concurrency policies to cancel in-progress runs, and gallery scripts are updated to support backup data URLs via Zenodo alongside primary GitHub sources. The underlying download_file utility function is enhanced to accept optional backup URLs and implement fallback retry logic with detailed error handling.

Changes

Cohort / File(s) Summary
GitHub Actions Concurrency
.github/workflows/ci.yml, .github/workflows/execute_notebooks.yml, .github/workflows/static.yml
Added or updated concurrency blocks to cancel in-progress workflow runs when new pushes occur on the same branch/PR, preventing overlapping executions.
Gallery Script Data Sources
docs/gallery_scripts_template/plot_chromatogram.py, docs/gallery_scripts_template/plot_investigate_spectrum_binning_ms_matplotlib.py, docs/gallery_scripts_template/plot_manuscript_d_fructose_spectrum_prediction_ms_matplotlib.py, docs/gallery_scripts_template/plot_mobilogram.py, docs/gallery_scripts_template/plot_peakmap.py, docs/gallery_scripts_template/plot_peakmap_3D.py, docs/gallery_scripts_template/plot_peakmap_binning_demonstration_ms_matplotlib.py, docs/gallery_scripts_template/plot_peakmap_marginals.py, docs/gallery_scripts_template/plot_spectrum.py, docs/gallery_scripts_template/plot_spectrum_dia.py, docs/gallery_scripts_template/plot_spyogenes_subplots_ms_bokeh.py, docs/gallery_scripts_template/plot_spyogenes_subplots_ms_matplotlib.py, docs/gallery_scripts_template/plot_spyogenes_subplots_ms_plotly.py
Updated data download mechanisms to use primary GitHub URLs with Zenodo backup URLs; added backup_url variable and updated download_file calls to pass the backup parameter for resilient data retrieval.
Download Utility Enhancement
pyopenms_viz/util.py
Enhanced download_file function to accept optional backup_url parameter, implement multi-URL retry logic with 30s timeout, add per-URL error handling for HTTP and connection errors, determine binary mode by file extension, and raise detailed RuntimeError if all URLs fail. Updated docstring to document new parameter and behavior.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • alter url request to pretend to be user #105: Directly related as both PRs modify the download_file function in pyopenms_viz/util.py; the earlier PR introduced the utility with user-agent behavior, while this PR adds backup URL support and multi-URL retry logic.

Poem

🐰 Backup URLs hop through the code,
GitHub and Zenodo light the road,
When one link stumbles, one takes flight,
Our downloads now twice as bright! ✨

✨ Finishing touches
  • 📝 Generate docstrings

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.

@singjc singjc merged commit 6bba6bc into OpenMS:main Jan 17, 2026
12 of 15 checks passed
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses documentation build failures caused by Zenodo rate limiting by switching to GitHub as the primary download source with Zenodo as a fallback. This improves reliability when building documentation and executing notebooks.

Changes:

  • Enhanced download_file() utility function to support backup URLs with retry logic and detailed error messaging
  • Updated all gallery script templates to use GitHub raw/release URLs as primary source with Zenodo as backup
  • Added concurrency controls to GitHub Actions workflows to cancel in-progress runs when new pushes occur

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
pyopenms_viz/util.py Refactored download_file function to support backup URLs, retry logic, and enhanced error handling
docs/gallery_scripts_template/*.py Updated 13 gallery scripts to use GitHub URLs as primary source with Zenodo backup
.github/workflows/static.yml Added cancel-in-progress to concurrency settings
.github/workflows/execute_notebooks.yml Added concurrency control with cancel-in-progress
.github/workflows/ci.yml Added concurrency control with cancel-in-progress

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +55 to +58
if i < len(urls_to_try) - 1:
print(f"Warning: {error_msg}\n Trying backup URL...")
else:
print(f"Error: {error_msg}")
Copy link

Copilot AI Jan 17, 2026

Choose a reason for hiding this comment

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

The error messages on lines 56 and 58 will include the detailed error_msg which is already marked as either "Warning" or "Error" based on whether there are more URLs to try. However, the prefix in the print statements adds another "Warning:" or "Error:" label, resulting in duplicate labeling. Consider simplifying the print statements to avoid redundancy, such as using just print(error_msg) when i == len(urls_to_try) - 1, since error_msg doesn't include the "Warning:" or "Error:" prefix itself.

Copilot uses AI. Check for mistakes.
Comment on lines +39 to +50
error_msg = (
f"Failed to download from URL ({i + 1}/{len(urls_to_try)}): {try_url}\n"
f" HTTP Status: {e.response.status_code}\n"
f" Reason: {e.response.reason}"
)
# Check for common error codes and provide helpful messages
if e.response.status_code == 403:
error_msg += (
"\n Note: 403 Forbidden often means the server is blocking automated requests "
"(rate limiting, bot detection, or access restrictions)."
)
elif e.response.status_code == 404:
Copy link

Copilot AI Jan 17, 2026

Choose a reason for hiding this comment

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

When catching requests.exceptions.HTTPError, the code accesses e.response.status_code and e.response.reason without checking if e.response is not None. While HTTPError typically has a response attribute populated, it's better to add a defensive check to prevent potential AttributeError if the response attribute is None in edge cases.

Suggested change
error_msg = (
f"Failed to download from URL ({i + 1}/{len(urls_to_try)}): {try_url}\n"
f" HTTP Status: {e.response.status_code}\n"
f" Reason: {e.response.reason}"
)
# Check for common error codes and provide helpful messages
if e.response.status_code == 403:
error_msg += (
"\n Note: 403 Forbidden often means the server is blocking automated requests "
"(rate limiting, bot detection, or access restrictions)."
)
elif e.response.status_code == 404:
resp = e.response
status_code = resp.status_code if resp is not None else "N/A"
reason = resp.reason if resp is not None else "No response available"
error_msg = (
f"Failed to download from URL ({i + 1}/{len(urls_to_try)}): {try_url}\n"
f" HTTP Status: {status_code}\n"
f" Reason: {reason}"
)
# Check for common error codes and provide helpful messages
if resp is not None and resp.status_code == 403:
error_msg += (
"\n Note: 403 Forbidden often means the server is blocking automated requests "
"(rate limiting, bot detection, or access restrictions)."
)
elif resp is not None and resp.status_code == 404:

Copilot uses AI. Check for mistakes.
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.

2 participants