StaticFetcher() Implementation + from_pdb() refactor - #5436
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #5436 +/- ##
===========================================
- Coverage 93.85% 93.84% -0.02%
===========================================
Files 182 183 +1
Lines 22509 22618 +109
Branches 3202 3221 +19
===========================================
+ Hits 21125 21225 +100
- Misses 922 929 +7
- Partials 462 464 +2 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
yuxuanzhuang
left a comment
There was a problem hiding this comment.
I left a few initial comments. My main concern is the cache and registry behavior, particularly for repeated fetches, pre-existing or unrelated cache files, and single- versus multiple-file inputs. Could you test these edge cases and add regression tests that confirm the intended behavior?
I likely won’t have time for another review this week, but please work on:
- Get all CI checks passing. (I think old failures should get fixed once you merge to develop)
- Improve test coverage (see Codecov)
|
|
||
| downloader = pooch.create( | ||
| path=cache_path, | ||
| fetcher = StaticFetcher(cache_path=cache_path) |
There was a problem hiding this comment.
I think there's an issue with how cache works. If I run
> from_PDB(['9BUY'])
PosixPath('~/Library/Caches/MDAnalysis_pdbs/9BUY.cif.gz')
from_PDB(['3SN6'])
ValueError: fetch() is requesting files not found in the registry. xxxIt's also unclear to me whether cache_path will proceed os env MDANALYSIS_FETCHER_DATA
There was a problem hiding this comment.
and the error suggested setting append_db and it's not an argument for from_PDB
| ValueError | ||
| For an invalid file format. Supported file formats are under Notes. | ||
|
|
||
| :class:`requests.exceptions.HTTPError` |
There was a problem hiding this comment.
If a PDB code with no legacy PDB format download https://www.rcsb.org/structure/9BUY ; is it possible to raise some more detailed error e.g. LegacyPDBDownloadError and suggest to use cif file.
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?
| 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.
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.