Skip to content
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

Interact.jl widgets not getting rendered on jupyter-notebook #372

Closed
agarie opened this issue Aug 21, 2020 · 7 comments
Closed

Interact.jl widgets not getting rendered on jupyter-notebook #372

agarie opened this issue Aug 21, 2020 · 7 comments

Comments

@agarie
Copy link

agarie commented Aug 21, 2020

Hi! I'm just getting started with Interact, so I'm sorry if this issue is due to my inexperience with the Julia ecosystem.

I have a notebook with the following code:

using Interact
s = slider(0:.1:1,label="Slider X:")

resulting in the following:

Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Scope(Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Node{WebIO.DOM}(WebIO.DOM(:html, :label), Any["Slider X:"], Dict{Symbol,Any}(:className => "interact ",:style => Dict{Any,Any}(:padding => "5px 10px 0px 10px")))], Dict{Symbol,Any}(:className => "interact-flex-row-left")), Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Node{WebIO.DOM}(WebIO.DOM(:html, :input), Any[], Dict{Symbol,Any}(:max => 11,:min => 1,:attributes => Dict{Any,Any}(:type => "range",Symbol("data-bind") => "numericValue: index, valueUpdate: 'input', event: {change: function (){this.changes(this.changes()+1)}}","orient" => "horizontal"),:step => 1,:className => "slider slider is-fullwidth",:style => Dict{Any,Any}()))], Dict{Symbol,Any}(:className => "interact-flex-row-center")), Node{WebIO.DOM}(WebIO.DOM(:html, :div), Any[Node{WebIO.DOM}(WebIO.DOM(:html, :p), Any[], Dict{Symbol,Any}(:attributes => Dict("data-bind" => "text: formatted_val")))], Dict{Symbol,Any}(:className => "interact-flex-row-right"))], Dict{Symbol,Any}(:className => "interact-flex-row interact-widget")), Dict{String,Tuple{Observables.AbstractObservable,Union{Nothing, Bool}}}("changes" => (Observable{Int64} with 1 listeners. Value:
0, nothing),"index" => (Observable{Any} with 2 listeners. Value:
6, nothing)), Set{String}(), nothing, Asset[Asset("js", "knockout", "/Users/caj/.julia/packages/Knockout/IP1uR/src/../assets/knockout.js"), Asset("js", "knockout_punches", "/Users/caj/.julia/packages/Knockout/IP1uR/src/../assets/knockout_punches.js"), Asset("js", nothing, "/Users/caj/.julia/packages/InteractBase/sOe2Z/src/../assets/all.js"), Asset("css", nothing, "/Users/caj/.julia/packages/InteractBase/sOe2Z/src/../assets/style.css"), Asset("css", nothing, "/Users/caj/.julia/packages/Interact/SbgIk/src/../assets/bulma_confined.min.css")], Dict{Any,Any}("changes" => Any[WebIO.JSString("(function (val){return (val!=this.model[\"changes\"]()) ? (this.valueFromJulia[\"changes\"]=true, this.model[\"changes\"](val)) : undefined})")],"index" => Any[WebIO.JSString("(function (val){return (val!=this.model[\"index\"]()) ? (this.valueFromJulia[\"index\"]=true, this.model[\"index\"](val)) : undefined})")]), WebIO.ConnectionPool(Channel{Any}(sz_max:32,sz_curr:0), Set{AbstractConnection}(), Base.GenericCondition{Base.AlwaysLockedST}(Base.InvasiveLinkedList{Task}(Task (runnable) @0x00000001162e3610, Task (runnable) @0x00000001162e3610), Base.AlwaysLockedST(1))), WebIO.JSString[WebIO.JSString("function () {\n    var handler = (function (ko, koPunches) {\n    ko.punches.enableAll();\n    ko.bindingHandlers.numericValue = {\n        init: function(element, valueAccessor, allBindings, data, context) {\n            var stringified = ko.observable(ko.unwrap(valueAccessor()));\n            stringified.subscribe(function(value) {\n                var val = parseFloat(value);\n                if (!isNaN(val)) {\n                    valueAccessor()(val);\n                }\n            });\n            valueAccessor().subscribe(function(value) {\n                var str = JSON.stringify(value);\n                if ((str == \"0\") && ([\"-0\", \"-0.\"].indexOf(stringified()) >= 0))\n                     return;\n                 if ([\"null\", \"\"].indexOf(str) >= 0)\n                     return;\n                stringified(str);\n            });\n            ko.applyBindingsToNode(\n                element,\n                {\n                    value: stringified,\n                    valueUpdate: allBindings.get('valueUpdate'),\n                },\n                context,\n            );\n        }\n    };\n    var json_data = {\"formatted_vals\":[\"0.0\",\"0.1\",\"0.2\",\"0.3\",\"0.4\",\"0.5\",\"0.6\",\"0.7\",\"0.8\",\"0.9\",\"1.0\"],\"changes\":WebIO.getval({\"name\":\"changes\",\"scope\":\"5742539691840127748\",\"id\":\"14016215829043600783\",\"type\":\"observable\"}),\"index\":WebIO.getval({\"name\":\"index\",\"scope\":\"5742539691840127748\",\"id\":\"11122984423837624543\",\"type\":\"observable\"})};\n    var self = this;\n    function AppViewModel() {\n        for (var key in json_data) {\n            var el = json_data[key];\n            this[key] = Array.isArray(el) ? ko.observableArray(el) : ko.observable(el);\n        }\n        \n        [this[\"formatted_val\"]=ko.computed(    function(){\n        return this.formatted_vals()[parseInt(this.index())-(1)];\n    }\n,this)]\n        [this[\"changes\"].subscribe((function (val){!(this.valueFromJulia[\"changes\"]) ? (WebIO.setval({\"name\":\"changes\",\"scope\":\"5742539691840127748\",\"id\":\"14016215829043600783\",\"type\":\"observable\"},val)) : undefined; return this.valueFromJulia[\"changes\"]=false}),self),this[\"index\"].subscribe((function (val){!(this.valueFromJulia[\"index\"]) ? (WebIO.setval({\"name\":\"index\",\"scope\":\"5742539691840127748\",\"id\":\"11122984423837624543\",\"type\":\"observable\"},val)) : undefined; return this.valueFromJulia[\"index\"]=false}),self)]\n        \n    }\n    self.model = new AppViewModel();\n    self.valueFromJulia = {};\n    for (var key in json_data) {\n        self.valueFromJulia[key] = false;\n    }\n    ko.applyBindings(self.model, self.dom);\n}\n);\n    (WebIO.importBlock({\"data\":[{\"name\":\"knockout\",\"type\":\"js\",\"url\":\"/assetserver/11f507ac8a8d4235efeb3c82e28f98bd7b561322-knockout.js\"},{\"name\":\"knockout_punches\",\"type\":\"js\",\"url\":\"/assetserver/9e94a58ea3cc98119b896fcd872afaffc7e25b8f-knockout_punches.js\"}],\"type\":\"async_block\"})).then((imports) => handler.apply(this, imports));\n}\n")])], Dict{Symbol,Any}(:className => "field interact-widget"))

I'm on macOS 10.15.6 with Julia 1.5 installed with Homebrew. I installed the nbextension as instructed in the README as well. My configurations is:

$ jupyter --version
jupyter core     : 4.6.3
jupyter-notebook : 6.1.3
qtconsole        : not installed
ipython          : 7.17.0
ipykernel        : 5.3.4
jupyter client   : 6.1.6
jupyter lab      : not installed
nbconvert        : 5.6.1
ipywidgets       : 7.5.1
nbformat         : 5.0.7
traitlets        : 4.3.3

$ jupyter nbextension list
Known nbextensions:
  config dir: /Users/caj/.jupyter/nbconfig
    notebook section
      webio-jupyter-notebook  enabled
      - Validating: OK
      jupyter-js-widgets/extension  enabled
      - Validating: OK
  config dir: /usr/local/etc/jupyter/nbconfig
    notebook section
      jupyter-js-widgets/extension  enabled
      - Validating: OK

What could be causing this? Do you have any suggestion as to what I could do to debug this? I'll be happy to give any more information if necessary.

@shashi
Copy link
Member

shashi commented Aug 21, 2020

Did you restart Jupyter server and open a new notebook and try?

@agarie
Copy link
Author

agarie commented Aug 21, 2020

@shashi Yes. I reproduced this issue with a new notebook (after restarting the Jupyter server) in which the only content were the cells containing the code shown on my initial post.

@lysogeny
Copy link

I encountered a possibly similar issue.

First of all, I noticed that the library worked when I ran it on my local machine. The trouble started when I tried to use Interact.jl on my server's jupyter notebook server. There I have a jupyter server behind an nginx reverse proxy on /jupyter. Similarly to agarie's issue, buttons and sliders just wouldn't show up.

In my browser's devtools I noticed that several requests return 404, e.g. for http://{server}/assetserver/86a580a22f01186f16f4a4ebde37669899bd7bbd-knockout.js. This makes sense as nginx is not serving anything on /assetserver, and it should be /jupyter/assetserver[...].

I don't know if it is possible to configure this somewhere, or if the c.NotebookApp.base_url from jupyter's config can be used.
I haven't looked too far into this, however I suspect that this problem might actually a WebIO.jl problem.

For now I have added the following temporary fix into my nginx config:

server {
    rewrite ^/assetserver/(.*) /jupyter/assetserver/$1 break;
    [...]
}

@matthijscox
Copy link

matthijscox commented Sep 7, 2020

I encountered the exact same issue, I haven't solved it fully yet, but it seems related to (automatically) rendering WebIO nodes. When I explicitly import WebIO, I can make it show the slider:

image

However, this doesn't solve all my Interact issues. observe(s) doesnt seem to work, @manipulate doesn't work either for me

@matthijscox
Copy link

matthijscox commented Sep 7, 2020

Ok I see now that my Interact and InteractBase builds are failing. It fails to download the css for Interact:

image

Interact issue 333 seems related.
Also I'm now reading Julia Discourse: Problem with curl.exe

@matthijscox
Copy link

matthijscox commented Sep 7, 2020

Ok fixed it by getting the builds working. I followed the solution from the [discourse post] to get curl.exe working (https://discourse.julialang.org/t/problem-with-curl-exe-windows-and-package-installation/29525/53):

  1. Open a command prompt, and type echo %APPDATA% to get the personal app data folder.
  2. Create an empty file called _curlrc in the app data folder.
  3. Write insecure on that file and save.
  4. import Pkg; Pkg.build("Interact")

Now the tutorial works directly:

image

@agarie
Copy link
Author

agarie commented Sep 17, 2020

Ok fixed it by getting the builds working. I followed the solution from the [discourse post] to get curl.exe working (https://discourse.julialang.org/t/problem-with-curl-exe-windows-and-package-installation/29525/53):

1. Open a command prompt, and type echo %APPDATA% to get the personal app data folder.

2. Create an empty file called _curlrc in the app data folder.

3. Write insecure on that file and save.

4. import Pkg; Pkg.build("Interact")

I did the same thing on macOS by creating a .curlrc on $HOME with insecure written on it then rebuilding Interact. It worked as well. Please remember to delete that .curlrc after that, tho. :P

I'm closing this issue now.

@agarie agarie closed this as completed Sep 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants