napari: KeyError: 'version' when installing a plugin
đ Bug
KeyError: âversionâ when installing a plugin (that is on pypi but not yet on napari hub). This error is maybe the reason why the warning message âWhen installing/uninstalling npe2 plugins, you must restart napari for UI changes to take effect.â is not displayingâŚ
To Reproduce
Steps to reproduce the behavior:
- Install the
napari-deepfinder
plugin from the UI by typingnapari-deepfinder
in the text bar. - The
KeyError Traceback (most recent call last)
File /home/cnstt/test-nap/venv1/lib/python3.9/site-packages/superqt/utils/_qthreading.py:616, in create_worker.<locals>.reraise(e=KeyError('version'))
615 def reraise(e):
--> 616 raise e
e = KeyError('version')
File /home/cnstt/test-nap/venv1/lib/python3.9/site-packages/superqt/utils/_qthreading.py:176, in WorkerBase.run(self=<napari._qt.qthreading.GeneratorWorker object>)
174 warnings.filterwarnings("always")
175 warnings.showwarning = lambda *w: self.warned.emit(w)
--> 176 result = self.work()
self = <napari._qt.qthreading.GeneratorWorker object at 0x7faf71497790>
177 if isinstance(result, Exception):
178 if isinstance(result, RuntimeError):
179 # The Worker object has likely been deleted.
180 # A deleted wrapped C/C++ object may result in a runtime
181 # error that will cause segfault if we try to do much other
182 # than simply notify the user.
File /home/cnstt/test-nap/venv1/lib/python3.9/site-packages/superqt/utils/_qthreading.py:443, in GeneratorWorker.work(self=<napari._qt.qthreading.GeneratorWorker object>)
441 try:
442 input = self._next_value()
--> 443 output = self._gen.send(input)
self = <napari._qt.qthreading.GeneratorWorker object at 0x7faf71497790>
input = None
output = (PackageMetadata(metadata_version='1.0', name='zarpaint', version='0.2.0', dynamic=None, platform=None, supported_platform=None, summary='Paint segmentations directly to on-disk/remote zarr arrays', description=None, description_content_type=None, keywords=None, home_page='https://github.com/jni/zarpaint', download_url=None, author='Abigail McGovern and Juan Nunez-Iglesias', author_email=None, maintainer=None, maintainer_email=None, license='BSD-3-Clause', classifier=None, requires_dist=None, requires_python=None, requires_external=None, project_url=None, provides_extra=None, provides_dist=None, obsoletes_dist=None), True)
self._gen = <generator object iter_hub_plugin_info at 0x7faf714d2c80>
444 self.yielded.emit(output)
445 except StopIteration as exc:
File /home/cnstt/test-nap/venv1/lib/python3.9/site-packages/napari/plugins/hub.py:101, in iter_hub_plugin_info(skip={}, conda_forge=False)
94 futures = [
95 executor.submit(hub_plugin_info, name, conda_forge=conda_forge)
96 for name in sorted(plugins)
97 if name not in skip
98 ]
100 for future in as_completed(futures):
--> 101 info, is_available_in_conda_forge = future.result()
future = <Future at 0x7faf7270c9d0 state=finished raised KeyError>
info, is_available_in_conda_forge = (PackageMetadata(metadata_version='1.0', name='zarpaint', version='0.2.0', dynamic=None, platform=None, supported_platform=None, summary='Paint segmentations directly to on-disk/remote zarr arrays', description=None, description_content_type=None, keywords=None, home_page='https://github.com/jni/zarpaint', download_url=None, author='Abigail McGovern and Juan Nunez-Iglesias', author_email=None, maintainer=None, maintainer_email=None, license='BSD-3-Clause', classifier=None, requires_dist=None, requires_python=None, requires_external=None, project_url=None, provides_extra=None, provides_dist=None, obsoletes_dist=None), True)
info = PackageMetadata(metadata_version='1.0', name='zarpaint', version='0.2.0', dynamic=None, platform=None, supported_platform=None, summary='Paint segmentations directly to on-disk/remote zarr arrays', description=None, description_content_type=None, keywords=None, home_page='https://github.com/jni/zarpaint', download_url=None, author='Abigail McGovern and Juan Nunez-Iglesias', author_email=None, maintainer=None, maintainer_email=None, license='BSD-3-Clause', classifier=None, requires_dist=None, requires_python=None, requires_external=None, project_url=None, provides_extra=None, provides_dist=None, obsoletes_dist=None)
is_available_in_conda_forge = True
102 if info and info not in already_yielded:
103 already_yielded.append(info)
File /usr/lib64/python3.9/concurrent/futures/_base.py:439, in Future.result(self=None, timeout=None)
437 raise CancelledError()
438 elif self._state == FINISHED:
--> 439 return self.__get_result()
self = None
441 self._condition.wait(timeout)
443 if self._state in [CANCELLED, CANCELLED_AND_NOTIFIED]:
File /usr/lib64/python3.9/concurrent/futures/_base.py:391, in Future.__get_result(self=None)
389 if self._exception:
390 try:
--> 391 raise self._exception
self = None
392 finally:
393 # Break a reference cycle with the exception in self._exception
394 self = None
File /usr/lib64/python3.9/concurrent/futures/thread.py:58, in _WorkItem.run(self=None)
55 return
57 try:
---> 58 result = self.fn(*self.args, **self.kwargs)
self = None
59 except BaseException as exc:
60 self.future.set_exception(exc)
File /home/cnstt/test-nap/venv1/lib/python3.9/site-packages/napari/plugins/hub.py:47, in hub_plugin_info(name='napari-deepfinder', min_dev_status=3, conda_forge=False)
44 except error.HTTPError:
45 return None, False
---> 47 version = info["version"]
info = {'conda': [], 'display_name': '', 'plugin_types': [], 'reader_file_extensions': [], 'writer_file_extensions': [], 'writer_save_layers': []}
48 norm_name = normalized_name(info["name"])
49 is_available_in_conda_forge = True
KeyError: 'version'
Expected behavior
This error should not happen!
Environment
napari: 0.4.16 Platform: Linux-5.18.10-100.fc35.x86_64-x86_64-with-glibc2.34 System: Fedora Linux 35 (Workstation Edition) Python: 3.9.13 (main, Jun 9 2022, 00:00:00) [GCC 11.3.1 20220421 (Red Hat 11.3.1-2)] Qt: 5.15.2 PyQt5: 5.15.7 NumPy: 1.23.1 SciPy: 1.8.1 Dask: 2022.7.1 VisPy: 0.10.0
OpenGL:
- GL version: 4.6.0 NVIDIA 515.48.07
- MAX_TEXTURE_SIZE: 16384
Screens:
- screen 1: resolution 1920x1200, scale 1.0
Plugins:
- console: 0.0.4
- napari-svg: 0.1.6
- scikit-image: 0.4.16
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 15 (10 by maintainers)
I would recommend this until we can properly spec and build an API that isnât just our frontend API exposed to the world đ
I suggested a revision to #4863 that should help to avoid any stray fields (since any real plugin will have a
name
): https://github.com/napari/napari/pull/4863/files#r929364346ok, well⌠use the PyPI API for now, and weâll put your PR on hold until we get some feedback from the hub team
yeah. thatâs cause the hub is only attempting to provide the metadata for plugins (not the actual plugin)⌠and it looks like somethingâs going on with their payloads at the moment
@goanpeca, @neuromusic ⌠if weâre going to use the hub API in napari code, it would be very handy if we had
TypedDicts
inhub.py
that would show us the structure weâre supposed to expect from those payloadsWhatâs fun is I just got this error when installing a different plugin! (napari-serialcellpose from GitHub):