StaticFetcher() Implementation + from_pdb() refactor - #5436
Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces a new MDAnalysis.fetch.fetchers.StaticFetcher abstraction for downloading/caching files via pooch, and refactors MDAnalysis.fetch.pdb.from_PDB() to use this new fetcher as its backend.
Changes:
- Adds
StaticFetcherimplementation with registry read/write/append helpers. - Refactors
from_PDB()to delegate downloads toStaticFetcher. - Adds/updates tests and Sphinx module docs for the new fetcher module.
Reviewed changes
Copilot reviewed 8 out of 9 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| testsuite/MDAnalysisTests/fetch/test_static_fetcher.py | New test coverage for StaticFetcher behavior and error cases. |
| testsuite/MDAnalysisTests/fetch/test_from_PDB.py | Updates from_PDB() tests for the refactored implementation. |
| testsuite/MDAnalysisTests/fetch/servers.py | Adds a local HTTP server helper for fetcher tests. |
| package/MDAnalysis/fetch/pdb.py | Refactors from_PDB() to use StaticFetcher and renames supported-format constant. |
| package/MDAnalysis/fetch/fetchers.py | Adds the StaticFetcher implementation and supporting utilities/constants. |
| package/MDAnalysis/fetch/init.py | Exposes StaticFetcher via package imports (but needs __all__ alignment). |
| package/doc/sphinx/source/documentation_pages/fetchers/fetchers.rst | Adds Sphinx automodule page for MDAnalysis.fetch.fetchers. |
| package/doc/sphinx/source/documentation_pages/fetchers_modules.rst | Registers the new fetchers documentation page in the module index. |
| .gitignore | Adds ignores for local scripts (should be reverted/clarified). |
Comments suppressed due to low confidence (2)
package/MDAnalysis/fetch/init.py:41
__all__does not includeStaticFetcher, but the module imports it, sofrom MDAnalysis.fetch import *will not export the new public symbol consistently.
__all__ = ["from_PDB"]
from .pdb import from_PDB
from .fetchers import StaticFetcher
package/MDAnalysis/fetch/fetchers.py:633
- In
_set_downloader(), whendownloader="auto"andbase_urldoesn't match the regex (or is missing a scheme),_downloaderis never set, leading toUnboundLocalError. Also, there is no default case for unsupported schemes, so the function can silently returnNone.
# Regex matching if downloader is set to auto
if downloader == "auto":
regex = r"^([^:]+):"
match = re.match(regex, base_url)
if match:
_downloader = match.group(1)
else:
_downloader = downloader
match _downloader:
case "http" | "https":
return pooch.HTTPDownloader(**kwargs)
case "ftp":
return pooch.FTPDownloader(**kwargs)
case "sftp":
return pooch.SFTPDownloader(**kwargs)
case "doi":
return pooch.DOIDownloader(**kwargs)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if APPEND_DATABASE and LOAD_FROM_CACHE: | ||
| self.append_registry(db_path, requested_files) | ||
|
|
There was a problem hiding this comment.
This is currently intentional. Should it be changed?
There was a problem hiding this comment.
Sleeping on it, I think the best behavior would have like an argument that making it so that the function appends to the registry unconditionally.
The default behavior should be the registry is not appended if there is a duplicate.
| import re | ||
| from pathlib import Path | ||
| from shutil import rmtree | ||
|
|
||
| from servers import temporary_http_server | ||
|
|
||
| import hashlib |
There was a problem hiding this comment.
Can you use
from .servers import temporary_http_server?
There was a problem hiding this comment.
This breaks testsuite/MDAnalysisTests/utils/test_imports.py
|
I have no idea what trigger copilot on this. I didn't turn on anything |
|
@jauy123 , the copilot reviews are currently enabled to automatically occur on all PRs. I am not sure if that was intentional or just a setting changed on GitHub. If you (or anyone else) wants to jump into a discussion, I posted on discord #developers https://discord.com/channels/807348386012987462/808088023957897258/1530342254256979978 |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 9 changed files in this pull request and generated 4 comments.
Comments suppressed due to low confidence (3)
testsuite/MDAnalysisTests/fetch/test_static_fetcher.py:28
from servers import ...is likely to fail under pytest because the test root is onsys.path, not this subdirectory, soservers.pymay not be importable as the top-level module nameservers. Import it via theMDAnalysisTestspackage namespace to make the test import robust.
from servers import temporary_http_server
testsuite/MDAnalysisTests/fetch/servers.py:55
- The test HTTP server binds to a fixed port (7123). This can cause spurious failures when the port is already in use (or when tests run in parallel). Binding to port 0 lets the OS pick a free ephemeral port.
server = ThreadingHTTPServer(("127.0.0.1", 7123), http_handler)
package/MDAnalysis/fetch/pdb.py:163
from_PDB(..., progressbar=...)forwardsprogressbarintoStaticFetcher.fetch()as an unknown kwarg.StaticFetcher.fetch()currently forwards unknown kwargs into the downloader constructor, which will likely raise aTypeError(e.g.,HTTPDownloader(..., progressbar=...)). Pass this through the existingverboseparameter instead.
return fetcher.fetch(
file_name=_pdb_ids,
base_url="https://files.wwpdb.org/download/",
progressbar=progressbar,
)
| if HAS_POOCH: | ||
| import pooch | ||
|
|
||
| REGISTRY_NAME = "hashes.txt" | ||
|
|
||
|
|
||
| @pytest.fixture() | ||
| def clean_up_default_cache(): | ||
| rmtree(pooch.os_cache(DEFAULT_CACHE_NAME_DOWNLOADER), ignore_errors=True) | ||
| yield | ||
| rmtree(pooch.os_cache(DEFAULT_CACHE_NAME_DOWNLOADER), ignore_errors=True) | ||
|
|
There was a problem hiding this comment.
Indeed, a fair comment.
However, by design, this fixture exists to test the StaticFetcher().fetch(cache_path=None) argument which is guarded by requiring pooch to run the corresponding test. All the other tests uses the tmp_path fixture instead.
So the NameError should never run in this case.
There was a problem hiding this comment.
To make it more obvious, I can add a guard saying that pooch is required for clean_up_default_cache()
Fixes #5429 and #5431
Changes made in this Pull Request:
fetch.fetchers.StaticFetcher()fetch.pdb.from_pdb()to useStaticFetchers()LLM / AI generated code disclosure
LLMs or other AI-powered tools (beyond simple IDE use cases) were used in this contribution: yes / no
From comment: #5436 (comment)
PR Checklist
package/CHANGELOGfile updated?package/AUTHORS? (If it is not, add it!)Developers Certificate of Origin
I certify that I can submit this code contribution as described in the Developer Certificate of Origin, under the MDAnalysis LICENSE.