-
Notifications
You must be signed in to change notification settings - Fork 39
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
importing a js library fails in Jupyter Hub, works in Jupyter Lab #385
Comments
Thank you for raising this issue. The problem you're encountering likely stems from the way Jupyter Widgets are installed and recognized within the Jupyter ecosystem, rather than an issue with your code. Jupyter Widgets need to be detected by Jupyter upon kernel startup, meaning you have to restart the kernel to load new widgets. This is a known limitation, distinct from how regular Python libraries are installed. For regular libraries, installation in user-land suffices, but widgets need to be installed in Jupyter Hub itself. I think I had with @hamelin at SciPy earlier this year about this very issue with classic Jupyter Widgets. Since To resolve this, you likely need need to install |
There might be two issues here: 1.) The difference between JupyterLab and Jupyter Hub for importing Anywidget relies on the browser's native module system (ESM). The specifier you provided isn't a valid module specifier (in this case, not a full URL) and the code it points to isn't ESM (doesn't include import * as phidget from "https://esm.sh/[email protected]";
export function render({ model, el }) {
} |
I would like to echo this from a slightly different perspective. Jupyter Widgets require Javascript extension code that Jupyter Lab must know where to find. In a typical standalone Jupyter Lab install — a virtual environment (Python In a Jupyterhub installation, things get slightly different. Jupyterhub is deployed in some admin virtual environment, and made to run with enough power to authenticate users logging in. It includes Jupyter Lab in its environment, and when a user logs it, it spawns Jupyter Lab by running process Thus, @manzt comment is right: one makes it possible to run extension widgets in Jupyterhub by installing the widget packages in the environment from which Jupyter Lab is spawned, which typically corresponds to the one where Jupyterhub is installed. Then custom user kernels also install the widget packages, so as to be able to import them. When they do, the extension JS in the Jupyterhub environment gets seen and loaded, and things work as expected. This also means that folks must do their best to install the same version of the widget package in their kernel environment as is deployed in the Jupyterhub environment. Discrepancies in conventions and expectations on either side of the Python/Javascript divide yield further weird and frustrating issues. |
Couldn't have put it better myself. Thank you for such a clear description of the problem. I wonder where we could continue this discussion in the context of JupyterHub. Ideally there is a world where each user customizes their own widgets like they do their other dependencies. |
I believe the |
From anywidget's perspective, I am committed to reducing this friction as much as possible (without being able to change how the Jupyter ecosystem and widgets work). Only anywidget's JS extension code needs to be discovered by Jupyter Lab/Jupyterhub. The frontend code for widgets derived from anywidget are served from the user's customized Jupyter kernel. I've intensionally stripped back anywidget's frontend API (#138) to ideally ensure wider compatibility in the future. This means that users should be able to upgrade/downgrade their own custom widget that rely on anywidget, since only |
Holy smokes, I think I solved the problem. This import statement works in both J Lab and the classic notebooks:
Curiously, this next one does not. (suggested earlier in the comments above)
The solution seems kind of random to me, but I am very grateful to all the suggestions you folks gave, as they were very insightful and gave me a lot of options to experiment with. |
I'm glad that you were able to sort out your problem.
To be clear, this import does work, but you haven't actually imported anything into your code. Trying to access an exported member will throw a Also this exact code isn't suggested anywhere in this comment thread. The snippet I shared uses a namespace (i.e., import * as phidget from "https://esm.sh/[email protected]"; which is a syntax is used to import all exported members from a module as a single object, in this case referred to as phidget.USBConnection
phidget.VoltageRatioInput I recommend reading about how modules work in the browser to learn more! |
I'm closing this issue to cleanup the issues in anywidget since the OP was resolved. Thank you for chiming in @hamelin. Hopefully we can elevate this discussion elsewhere to improve widgets. |
Yes, that has been quite a nightmare over the years, in solara we do some checking for classic notebook (i've tested this on AWS sagemaker): If we find that the python executable != server executable: https://github.com/widgetti/solara/blob/7bf2ce53c7ede6eec3883abdc7d5f2625e22ccd1/solara/checks.py#L199 We inject the following, and give a proper error msg what to do: https://github.com/widgetti/solara/blob/master/solara/checks.html Feedback on this is welcome, and ideas how to upstream this as well. |
FWIW In my own IPYwidget library buckaroo, I addressed some of this. I'm interested to hear about other approaches around this problem. It's a really poor experience for an initial user install. Maybe you could source the JS from unpackage when the user would encounter the problem. It would be great to have a standard best practice for dealing with this for all widget libraries. |
I'm creating an "anywidget" to access some hardware devices known as "Phidgets."
This requires importing a library of js code in the _esm file for the anywidget.
My import statement works fine in Jupyter Lab, but not in Jupyter Hub (the classic Jupyter notebook).
My question is: what is the proper way to import a js module into the _esm file?
This statement works in Jupyter Lab, but not in Hub (i.e. not in classic notebook):
_esm = """
import "https://unpkg.com/phidget22/browser/phidget22";
....
I've also tried the following, based on the examples in the anywidget docs:
import * as phidget22 from "https://unpkg.com/phidget22/browser/phidget22"; or
import USBConnection from "https://unpkg.com/phidget22/browser/phidget22";
But they don't work at all. So, what is the right way to import?
The text was updated successfully, but these errors were encountered: