[11/08/22 16:44:22] INFO Resolved project path as: __init__.py:132/Users/Nok_Lam_Chan/dev/kedro_gallery/jupyter-debug-demo. To set a different path, run '%reload_kedro <project_root>'
[11/08/22 16:44:24] INFO Kedro project jupyter_debug_demo __init__.py:101
INFO Defined global variable 'context', 'session', 'catalog' and __init__.py:102'pipelines'
INFO Running node: report_accuracy: report_accuracy([y_pred,y_test]) -> Nonenode.py:327
ERROR Node 'report_accuracy: report_accuracy([y_pred,y_test]) -> None' failed node.py:352 with error: Simulate some bug here
WARNING There are 1 nodes that have not run. runner.py:202 You can resume the pipeline run from the nearest nodes with persisted inputs by adding the following argument to your previous command: --from-nodes "report_accuracy"
Read from stack trace - find out the line of code that produce the error
Find which node this function belongs to
Trying to rerun the pipeline just before this node
If it’s not a persisted dataset, you need to change it in catalog.yml, and re-run the pipeline, error is thrown again
session has already been used once, so if you call session again it will throw error. (so he had a wrapper function that recreate session and do something similar to session.run
Create a new session or %reload_kedro and re-run?
This is not efficient because in interactive workflow, these intermdiate variables is likely store in the catalog already.
[11/08/22 16:46:49] INFO Resolved project path as: __init__.py:132/Users/Nok_Lam_Chan/dev/kedro_gallery/jupyter-debug-demo. To set a different path, run '%reload_kedro <project_root>'
[11/08/22 16:46:50] INFO Kedro project jupyter_debug_demo __init__.py:101
INFO Defined global variable 'context', 'session', 'catalog' and __init__.py:102'pipelines'
INFO Running node: report_accuracy: report_accuracy([y_pred,y_test]) -> Nonenode.py:327
ERROR Node 'report_accuracy: report_accuracy([y_pred,y_test]) -> None' failed node.py:352 with error: Simulate some bug here
WARNING There are 1 nodes that have not run. runner.py:202 You can resume the pipeline run from the nearest nodes with persisted inputs by adding the following argument to your previous command: --from-nodes "report_accuracy"
Copy the source code of func to notebook, it would work if the function itself is the node function, but if it is some function buried deep down, that’s a lot more copy-pasting and change of import maybe.
def report_accuracy(y_pred: pd.Series, y_test: pd.Series):"""Calculates and logs the accuracy. Args: y_pred: Predicted target. y_test: True target. """raiseValueError("Simulate some bug here") accuracy = (y_pred == y_test).sum() /len(y_test) logger = logging.getLogger(__name__) logger.info("Model has accuracy of %.3f on test data.", accuracy)
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮│/var/folders/dv/bz0yz1dn71d2hygq110k3xhw0000gp/T/ipykernel_7863/1415042900.py:1 in <cell line: ││1>││││[Errno 2] No such file or directory: ││'/var/folders/dv/bz0yz1dn71d2hygq110k3xhw0000gp/T/ipykernel_7863/1415042900.py'│╰──────────────────────────────────────────────────────────────────────────────────────────────────╯NameError: name 'pd' is not defined
This won’t work immediately work, a couple of copy&paste is needed
manual copy the imports
Remove the function now - copy the source code as a cell instead
import pandas as pdimport logging
raiseValueError("Simulate some bug here")accuracy = (y_pred == y_test).sum() /len(y_test)logger = logging.getLogger(__name__)logger.info("Model has accuracy of %.3f on test data.", accuracy)
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮│/var/folders/dv/bz0yz1dn71d2hygq110k3xhw0000gp/T/ipykernel_7863/2816569123.py:1 in <cell line: ││1>││││[Errno 2] No such file or directory: ││'/var/folders/dv/bz0yz1dn71d2hygq110k3xhw0000gp/T/ipykernel_7863/2816569123.py'│╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ValueError: Simulate some bug here
Assume we know that the first line is buggy, let’s remove it
# raise ValueError("Simulate some bug here")accuracy = (y_pred == y_test).sum() /len(y_test)logger = logging.getLogger(__name__)logger.info("Model has accuracy of %.3f on test data.", accuracy)# It now works - lets copy this block back into the function and rerun
Change the source code and make it work in the notebook
Rerun the pipeline to ensure everything works
session.run()
[11/08/22 16:50:48] INFO Resolved project path as: __init__.py:132/Users/Nok_Lam_Chan/dev/kedro_gallery/jupyter-debug-demo. To set a different path, run '%reload_kedro <project_root>'
[11/08/22 16:50:49] INFO Kedro project jupyter_debug_demo __init__.py:101
INFO Defined global variable 'context', 'session', 'catalog' and __init__.py:102'pipelines'
INFO Pipeline execution completed successfully. runner.py:90
{}
It works now!
Debugging with interactive session is not uncommon - compare to IDE/breakpoint. * You can make plots and see the data * You can intercept the variable and continue with the program - espeically useful when it is computation intensive.
More to optimize 1st PoC * %load_node - populate all neccessary data where the node throws error * When pipeline fail - raise something like %load_node debug=True - the traceback should have information about which node the error is coming from. * Is there anything we can use viz? Sometimes I get question from people can kedro-viz help with debugging too.
More to optimize: * What if the error is not in the node function but somewhere deeper in the call stack? * Handle case when the inputs are not in catalog - how to recompute the necessary inputs? Potentially we can use the backtracking to do it in a more efficient way.