Hi, thanks for maintaining this package.
I ran into an issue when calling EMDB().get_entry("EMD-6483"). The API request itself succeeds, but the Python wrapper fails while parsing the returned entry metadata.
Minimal reproduction
from emdb.client import EMDB
entry = EMDB().get_entry("EMD-6483")
Observed error
Traceback (most recent call last):
File ".../site-packages/emdb/client.py", line 40, in get_entry
return EMDBEntry.from_api(data, client=self)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".../site-packages/emdb/models/entry.py", line 118, in from_api
mask_file = MaskFile.from_api(m)
^^^^^^^^^^^^^^^^^^^^
File ".../site-packages/emdb/models/files.py", line 222, in from_api
map_file=BaseMapFile.from_api(data.get("mask_details", {})) if data.get("mask_details") else None,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".../site-packages/emdb/models/files.py", line 108, in from_api
return cls(
^^^^
TypeError: Can't instantiate abstract class BaseMapFile without an implementation for abstract method 'source_path'
During handling of the above exception, another exception occurred:
emdb.exceptions.EMDBAPIError: EMDB API Error: Failed to retrieve entry EMD-6483: Can't instantiate abstract class BaseMapFile without an implementation for abstract method 'source_path'
Environment
Python: 3.12
Package: emdb-api-wrapper / emdb
I observed this through a downstream dependency (cryopy.database.get_contour_level), but the minimal reproduction above fails directly with this package.
Expected behavior
EMDB().get_entry("EMD-6483") should return an EMDBEntry object successfully.
The raw EMDB API response for this entry appears to contain a valid contour level:
/map/contour_list/contour[0]/level = 0.03
/map/contour_list/contour[0]/primary = True
So the entry metadata is accessible from the API, but the wrapper fails during object construction.
Possible cause
The failure seems to happen while parsing mask metadata:
# emdb/models/files.py
map_file = (
BaseMapFile.from_api(data.get("mask_details", {}))
if data.get("mask_details")
else None
)
BaseMapFile is an abstract class because it has an abstract source_path property, so calling BaseMapFile.from_api(...) eventually attempts to instantiate an abstract class.
Maybe mask_details should be parsed into a concrete map-file class, or MaskFile.map_file should use a non-abstract concrete model for mask map details.
Why this matters
This breaks downstream workflows that only need fields such as primary_map.contour_list, because get_entry() parses the full entry and fails on unrelated mask metadata before the caller can access the contour level.
Thanks!
Hi, thanks for maintaining this package.
I ran into an issue when calling
EMDB().get_entry("EMD-6483"). The API request itself succeeds, but the Python wrapper fails while parsing the returned entry metadata.Minimal reproduction
Observed error
Environment
I observed this through a downstream dependency (
cryopy.database.get_contour_level), but the minimal reproduction above fails directly with this package.Expected behavior
EMDB().get_entry("EMD-6483")should return anEMDBEntryobject successfully.The raw EMDB API response for this entry appears to contain a valid contour level:
So the entry metadata is accessible from the API, but the wrapper fails during object construction.
Possible cause
The failure seems to happen while parsing mask metadata:
BaseMapFileis an abstract class because it has an abstractsource_pathproperty, so callingBaseMapFile.from_api(...)eventually attempts to instantiate an abstract class.Maybe
mask_detailsshould be parsed into a concrete map-file class, orMaskFile.map_fileshould use a non-abstract concrete model for mask map details.Why this matters
This breaks downstream workflows that only need fields such as
primary_map.contour_list, becauseget_entry()parses the full entry and fails on unrelated mask metadata before the caller can access the contour level.Thanks!