Add repository url to extension info
nbowditch-einblick opened this issue · 1 comments
Problem
The core issue I'm trying to solve is that our company's logo isn't showing up next to our extension in the Jupyterlab extension manager. However, as I will explain, this is due to a function defined here in the server code.
For reference:
I traced the issue down to this function here:
def get_federated_extensions(labextensions_path: list[str]) -> dict[str, Any]:
"""Get the metadata about federated extensions"""
federated_extensions = {}
for ext_dir in labextensions_path:
# extensions are either top-level directories, or two-deep in @org directories
for ext_path in chain(
iglob(pjoin(ext_dir, "[!@]*", "package.json")),
iglob(pjoin(ext_dir, "@*", "*", "package.json")),
):
with open(ext_path, encoding="utf-8") as fid:
pkgdata = json.load(fid)
if pkgdata["name"] not in federated_extensions:
data = dict(
name=pkgdata["name"],
version=pkgdata["version"],
description=pkgdata.get("description", ""),
url=get_package_url(pkgdata),
ext_dir=ext_dir,
ext_path=osp.dirname(ext_path),
is_local=False,
dependencies=pkgdata.get("dependencies", dict()),
jupyterlab=pkgdata.get("jupyterlab", dict()),
)
install_path = osp.join(osp.dirname(ext_path), "install.json")
if osp.exists(install_path):
with open(install_path, encoding="utf-8") as fid:
data["install"] = json.load(fid)
federated_extensions[data["name"]] = data
return federated_extensions
The data
object stored for each extension is missing an optional entry called repository
. This is used by jupyterlab to build a "repository_url"
field that it sends to the front-end, which the extension-manager may use to get a github user avatar to show next to the extension as a thumbnail.
Details
Each extension thumbnail is just a url pulled from whatever github user is associated with the extension's github page. The logic to get that github url is here. Basically it looks at 2 possible fields from the entry
object from the server: "homepage"
or "repository_url"
. We have our homepage set to the pypi page for our extension, so in theory it should look at the latter option.
However, if you look at all the extension entries we get back from the server, all of them have null
values for this "repository_url"
field, even if they have the appropriate properties set in their package.json:
...
"repository": {
"type": "git",
"url": "https://github.com/some-user/some-extension.git"
}
...
I traced this back to the manager.py file in jupyterlab's repo, where it attempts to set this value here:
...
repository_url=data.get("repository", {}).get("url", data.get("repository"))
...
The data
dict that it's reading is retrieved from the get_federated_extensions
function. If you take a look at that function above, you can notice that there's no logic to add a "repository"
field, so above will always evaluate to repository_url=None
.
Proposed Solution
In get_federated_extensions
, there should be some logic to check if the pkgdata
(read in from a package.json file) has a "repository"
field, and if so, whether that field's value is a dict with a "url"
field. If so, it should apply those values to the data for that extension returned:
def get_federated_extensions(labextensions_path: list[str]) -> dict[str, Any]:
"""Get the metadata about federated extensions"""
federated_extensions = {}
for ext_dir in labextensions_path:
# extensions are either top-level directories, or two-deep in @org directories
for ext_path in chain(
iglob(pjoin(ext_dir, "[!@]*", "package.json")),
iglob(pjoin(ext_dir, "@*", "*", "package.json")),
):
with open(ext_path, encoding="utf-8") as fid:
pkgdata = json.load(fid)
if pkgdata["name"] not in federated_extensions:
data = dict(
name=pkgdata["name"],
version=pkgdata["version"],
description=pkgdata.get("description", ""),
url=get_package_url(pkgdata),
ext_dir=ext_dir,
ext_path=osp.dirname(ext_path),
is_local=False,
dependencies=pkgdata.get("dependencies", dict()),
jupyterlab=pkgdata.get("jupyterlab", dict()),
)
# ####################################################
# NEW LOGIC START ####################################
# ####################################################
if "repository" in pkgdata and "url" in pkgdata.get("repository", {}):
data["repository"] = dict(url=pkgdata.get("repository").get("url"))
# ####################################################
# NEW LOGIC END ######################################
# ####################################################
install_path = osp.join(osp.dirname(ext_path), "install.json")
if osp.exists(install_path):
with open(install_path, encoding="utf-8") as fid:
data["install"] = json.load(fid)
federated_extensions[data["name"]] = data
return federated_extensions
Additional context
None
Thank you for opening your first issue in this project! Engagement like this is essential for open source projects! 🤗
If you haven't done so already, check out Jupyter's Code of Conduct. Also, please try to follow the issue template as it helps other other community members to contribute more effectively.
You can meet the other Jovyans by joining our Discourse forum. There is also an intro thread there where you can stop by and say Hi! 👋
Welcome to the Jupyter community! 🎉