plotly / dash

Data Apps & Dashboards for Python. No JavaScript Required.
https://plotly.com/dash
MIT License
21.25k stars 2.05k forks source link

dev tools: invoke debugger/logger ineractively #698

Open alexcjohnson opened 5 years ago

alexcjohnson commented 5 years ago

Now that we have the callback graph in the dev tools UI, let's use that to enable interactive callback debugging!

nicolaskruchten commented 5 years ago

From the front-end perspective, this adds back-end state to the callback chain that needs to be exposed to the front-end for display purposes. Right now the DAG is reactively drawn based on the information in the dependenciesRequest object in the redux store, so we would either need that object to be augmented to contain the "which callbacks are in which state" information (and that object needs to be kept up to date) or some equivalent other object needs to live in the store.

alexcjohnson commented 5 years ago

It's not back-end state - it's entirely up to the front end whether any given callback should be debugged or not. Two different people could be viewing the same app, one just using it normally and the other asking for debugging of various callbacks.

So I'd suggest adding another object to the redux store for "which callbacks are in which state." This is set by clicking callback circles, and is then fed back into redrawing those circles in a different color as well as used when making a callback request to determine whether to invoke debugging.

nicolaskruchten commented 5 years ago

🤦‍♂️ ok yes I read that totally wrong, sorry.

nicolaskruchten commented 5 years ago

With the current DAG implementation this will be fairly difficult as there's no easy way to add JS click handlers to the individual nodes.

We should investigate moving away from viz.js towards https://github.com/dagrejs or something like that to make this a real UI component.

rpkyle commented 5 years ago

@alexcjohnson @nicolaskruchten I'm really excited for this addition, I think it's going to be a game-changer for interactive debugging in DashR.

  • For breakpoint, wrap the callback in pdb.runcall, which starts pdb at the beginning of the function, in the server console (eventually perhaps we could pull this to the front end, but that sounds like a much bigger project). Then it's up to the user to run the debugger and allow the function to finish and return.
  • For logging we wrap the callback in the appropriate pysnooper call, capture the output, and return it with the output data, and display it in the error console. @rpkyle do both of these modes have equivalents in R?

To emulate breakpoint on the Python side in R, one option is to set a (logical/boolean) flag prior to firing the callback handler again which invokes browser(). We can't currently use RStudio breakpoints because Dash is an R6 class, and I don't think we should assume devs are using RStudio at all. browser() is universally supported.

For logging, I'll have to think a bit more. There's nothing quite like pysnooper in R, though R does have rudimentary built-in capture tools like sink, capture.output and savehistory:

https://stat.ethz.ch/R-manual/R-devel/library/base/html/sink.html https://stat.ethz.ch/R-manual/R-devel/library/utils/html/capture.output.html https://stat.ethz.ch/R-manual/R-devel/library/utils/html/savehistory.html

I'm not quite sure how we'd replicate the functionality of pysnooper with these, though.