-
Notifications
You must be signed in to change notification settings - Fork 77
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
Fix resizing plotly web clients #4806
base: main
Are you sure you want to change the base?
Conversation
Detect plotly plots and send as an HTML plot event Shows the localhost plot in Plots View
I'm working adding a test similar to what is there for Bokeh |
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.
Confirmed that plotly plots are resizing with the plots pane! My main concern is about circumventing the proxy server.
// Start an HTML proxy server for the file | ||
const uri = await this.startHtmlProxyServer(e.path); | ||
if (e.path.endsWith('.html') || e.path.endsWith('.htm')) { | ||
// Start an HTML proxy server for the file | ||
uri = await this.startHtmlProxyServer(e.path); | ||
} else { | ||
uri = URI.parse(e.path); | ||
} |
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.
Does it work without this change? This looks like it won't create a proxy server which I think wouldn't work on Workbench.
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.
This part I wasn't sure if it would work. When opening other URLs in the viewer, it doesn't proxy it. I'll try it out but I agree that I don't think it would work.
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.
It seems to work when running Positron server but it's all local. I think it's only working since the deepest iframe loads the plotly url.
@sharon-wang I think it probably needs a tweak on creating the proxy server or a slightly different type of proxy server. The one used for HTML files didn't seem to work with the localhost URL that plotly produces (file URI vs. localhost URL).
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.
Do you have some example plotly URI/URLs? On main
, python plotly plots work on Server Web and Workbench, so I wonder what changes to the URI/URLs are occurring?
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.
http://127.0.0.1:6728/
It's loading something like that with a random port. Before this change, it would load an HTML file and go through the HTMLProxy
. So I think it'll need to load the URL with a proxy as it did before.
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.
return True | ||
# pass back to webbrowser's list of browsers to open up the link | ||
return False | ||
|
||
|
||
def _is_module_function(self, module_name, function_name): |
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.
Nit: This could be a standalone function since self
is never used.
if module: | ||
for frame_info in inspect.stack(): | ||
if ( | ||
inspect.getmodule(frame_info.frame, frame_info.filename) == module |
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 initially wrote this code, and I've wondered if it would be safer to check only the module part and not the function. What do you think?
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.
It seemed to make sense to check the function too but I don't think I know enough about Python to foresee any problems. I suppose removing the function check would handle any new calls that Bokeh or Plotly might add.
Then it could work in that scenario without having to do anything. Keeping the check would definitely not work in that case so there's nothing to lose?
if os.name == "nt": | ||
url = urlparse(url).netloc or urlparse(url).path | ||
|
||
return self._comm.send_event( |
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 think webbrowser
expects this method to return a boolean: True
if we've handled the request.
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.
Should we be calling _send_show_html_event
here?
if is_plot: | ||
if os.name == "nt": | ||
url = urlparse(url).netloc or urlparse(url).path | ||
event = ShowUrlParams(url=url) |
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.
event = ShowUrlParams(url=url) |
|
||
def _send_show_html_event(self, url, is_plot): | ||
if self._comm is None: | ||
return False |
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.
We should log a warning here.
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.
Good idea
return False | ||
|
||
|
||
def _send_show_html_event(self, url, is_plot): |
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.
Could you please add type annotations to this and _is_module_function
?
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.
Annotations added
if os.name == "nt": | ||
url = urlparse(url).netloc or urlparse(url).path |
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.
Maybe this can be moved to _send_show_html_event
?
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've moved it into the new function
I added a unit test but it doesn't work locally. It hangs after making the call to send the comm event. Not really sure what's going on here? |
I had to mock |
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.
Did not build/test this since others have.
A little nitpicky, but I'd prefer not to overload ShowHtmlFile
if we're sending a URL rather than a HTML file path. There's ShowUrl
already; we could add a param to that method to indicate a plot, or create a different event to handle this brand of URLs.
If we do need to overload ShowHtmlFile, maybe we could check for file:
/ http:
URIs rather than checking the file extension?
@jmcphers I think that change will be reverted if the fix in #4855 works for Tim -- the approach in #4855 is to check the URI scheme in |
Address #4245
Sets Plotly to use its browser renderer. When calling
show()
, we intercept and send an event so that the URL is displayed in a webview in the Plots View instead of the viewer (or in the Viewer if the preference is set).Plotly's browser renderer fills width and height to 100% when no plot size is defined compared to the JupyterLab renderer (or vscode?) that defaults to Plots View's width and height 450px. Underneath, the browser renderer sets
responsive: True
for the config, which will set width and height to 100%.I'm not sure about the proxy part. We don't create one for the Viewer so I'm not sure if this will need more work when using this in Posit Workbench.
QA Notes
Code to generate a Plotly plot.
pip install plotly
before running.Disable this setting so the plot shows in Plots instead of the Viewer.