-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Move npe2api.py from napari repo to this repo #39
Merged
Merged
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
cc76d55
Update plugin dialog design & functionality to add conda install (#5198)
ppwadhwa 9c7a984
Maint: Bump mypy (#5727)
Czaki 6419819
Remove support for briefcase installers (#5804)
jaimergp b9b4398
MAINT: Fix more typing and enable mypy on more files. (#5897)
Carreau 05bbeea
Fix check if plugin is available from conda (#6545)
Czaki 58c4c74
pre-commit autoupdate (#6581)
pre-commit-ci[bot] 6f93b39
Use ruff to format strings to single quotes. (#6407)
Czaki a73d915
Drop Python 3.8, add Python 3.12 testing (#6738)
Czaki bed9b6a
Add extra field to store plugin display name (#6841)
goanpeca bd61911
Update `hypothesis`, `pytest`, `virtualenv`, bump mypy constraints an…
napari-bot 7323170
Add warning notification when connectivity errors occur in when openi…
goanpeca 9080174
Move npe2api.py from napari repo to this repo
goanpeca 8671672
Fix and updte import
goanpeca File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
""" | ||
These convenience functions will be useful for searching pypi for packages | ||
that match the plugin naming convention, and retrieving related metadata. | ||
""" | ||
|
||
import json | ||
from collections.abc import Iterator | ||
from concurrent.futures import ThreadPoolExecutor | ||
from functools import lru_cache | ||
from typing import ( | ||
Optional, | ||
TypedDict, | ||
cast, | ||
) | ||
from urllib.error import HTTPError, URLError | ||
from urllib.request import Request, urlopen | ||
|
||
from napari.plugins.utils import normalized_name | ||
from napari.utils.notifications import show_warning | ||
from npe2 import PackageMetadata | ||
from typing_extensions import NotRequired | ||
|
||
PyPIname = str | ||
|
||
|
||
@lru_cache | ||
def _user_agent() -> str: | ||
"""Return a user agent string for use in http requests.""" | ||
import platform | ||
|
||
from napari import __version__ | ||
from napari.utils import misc | ||
|
||
if misc.running_as_constructor_app(): | ||
env = 'constructor' | ||
elif misc.in_jupyter(): | ||
env = 'jupyter' | ||
elif misc.in_ipython(): | ||
env = 'ipython' | ||
else: | ||
env = 'python' | ||
|
||
parts = [ | ||
('napari', __version__), | ||
('runtime', env), | ||
(platform.python_implementation(), platform.python_version()), | ||
(platform.system(), platform.release()), | ||
] | ||
return ' '.join(f'{k}/{v}' for k, v in parts) | ||
|
||
|
||
class _ShortSummaryDict(TypedDict): | ||
"""Objects returned at https://npe2api.vercel.app/api/extended_summary .""" | ||
|
||
name: NotRequired[PyPIname] | ||
version: str | ||
summary: str | ||
author: str | ||
license: str | ||
home_page: str | ||
|
||
|
||
class SummaryDict(_ShortSummaryDict): | ||
display_name: NotRequired[str] | ||
pypi_versions: NotRequired[list[str]] | ||
conda_versions: NotRequired[list[str]] | ||
|
||
|
||
def plugin_summaries() -> list[SummaryDict]: | ||
"""Return PackageMetadata object for all known napari plugins.""" | ||
url = 'https://npe2api.vercel.app/api/extended_summary' | ||
with urlopen(Request(url, headers={'User-Agent': _user_agent()})) as resp: | ||
return json.load(resp) | ||
|
||
|
||
@lru_cache | ||
def conda_map() -> dict[PyPIname, Optional[str]]: | ||
"""Return map of PyPI package name to conda_channel/package_name ().""" | ||
url = 'https://npe2api.vercel.app/api/conda' | ||
with urlopen(Request(url, headers={'User-Agent': _user_agent()})) as resp: | ||
return json.load(resp) | ||
|
||
|
||
def iter_napari_plugin_info() -> Iterator[tuple[PackageMetadata, bool, dict]]: | ||
"""Iterator of tuples of ProjectInfo, Conda availability for all napari plugins.""" | ||
try: | ||
with ThreadPoolExecutor() as executor: | ||
data = executor.submit(plugin_summaries) | ||
_conda = executor.submit(conda_map) | ||
|
||
conda = _conda.result() | ||
data_set = data.result() | ||
except (HTTPError, URLError): | ||
show_warning( | ||
'There seems to be an issue with network connectivity. ' | ||
'Remote plugins cannot be installed, only local ones.\n' | ||
) | ||
return | ||
|
||
conda_set = {normalized_name(x) for x in conda} | ||
for info in data_set: | ||
info_copy = dict(info) | ||
info_copy.pop('display_name', None) | ||
pypi_versions = info_copy.pop('pypi_versions') | ||
conda_versions = info_copy.pop('conda_versions') | ||
info_ = cast(_ShortSummaryDict, info_copy) | ||
|
||
# TODO: use this better. | ||
# this would require changing the api that qt_plugin_dialog expects to | ||
# receive | ||
|
||
# TODO: once the new version of npe2 is out, this can be refactored | ||
# to all the metadata includes the conda and pypi versions. | ||
extra_info = { | ||
'home_page': info_.get('home_page', ''), | ||
'display_name': info.get('display_name', ''), | ||
'pypi_versions': pypi_versions, | ||
'conda_versions': conda_versions, | ||
} | ||
info_['name'] = normalized_name(info_['name']) | ||
meta = PackageMetadata(**info_) # type:ignore[call-arg] | ||
|
||
yield meta, (info_['name'] in conda_set), extra_info |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd normally type it like that but it looks weird :/