Repository: kedro-org/kedro
File: kedro/ipython/__init__.py (Python)

Code before:
    """Prepare the code to load dataset from catalog, import statements and function body.

    Args:
        node_name (str): The name of the node.

    Returns:
        list[str]: A list of string which is the generated code, each string represent a
        notebook cell.
    """
    node = _find_node(node_name)
    node_func = node.func

    node_inputs = _prepare_node_inputs(node)
    imports = _prepare_imports(node_func)
    function_text = _prepare_function_body(node_func)
    function_text = "# Function Body\n" + function_text

    cells: list[str] = []
    cells.append(node_inputs)
    cells.append(imports)
    cells.append(function_text)
    return cells


def _find_node(node_name: str) -> Node:
    for pipeline in pipelines.values():
        try:
            found_node: Node = pipeline.filter(node_names=[node_name]).nodes[0]
            return found_node
        except ValueError:
            continue
    # If reached the node was not found in the project
    raise ValueError(f"Node {node_name} is not found in any pipelines.")


def _prepare_imports(node_func: Callable) -> str:
    """Prepare the import statements for loading a node."""
    python_file = inspect.getsourcefile(node_func)
    logger.info(f"Loading node defintion from {python_file}")

    # Confirm source file was found
    if python_file:
        import_statement = []
        with open(python_file) as file:
            # Parse any line start with from or import statement
            for line in file.readlines():
                if line.startswith("from") or line.startswith("import"):
                    import_statement.append(line.strip())

        clean_imports = "\n".join(import_statement).strip()
        return clean_imports

Review comment (bug):
To make this easier to debug, is there a chance we turn `pipelines` into an actual parameter?

```suggestion
def _find_node(node_name: str, pipelines: ...) -> Node:
    for pipeline in pipelines.values():
```

the caller would have to be modified as well of course.

In general I'm not a fan of how `pipelines` comes `from kedro.framework.project`, but that's another story.

Code after:
def _load_node(node_name: str, pipelines: _ProjectPipelines) -> list[str]:
    """Prepare the code to load dataset from catalog, import statements and function body.

    Args:
        node_name (str): The name of the node.

    Returns:
        list[str]: A list of string which is the generated code, each string represent a
        notebook cell.
    """
    warnings.warn(
        "This is an experimental feature, only Jupyter Notebook (>7.0) & Jupyter Lab "
        "are supported. If you encounter unexpected behaviour or would like to suggest "
        "feature enhancements, add it under this github issue https://github.com/kedro-org/kedro/issues/3580"
    )
    node = _find_node(node_name, pipelines)
    node_func = node.func

    node_inputs = _prepare_node_inputs(node)
    imports = _prepare_imports(node_func)
    function_definition = _prepare_function_body(node_func)
    function_call = _prepare_function_call(node_func)

    cells: list[str] = []
    cells.append(node_inputs)
    cells.append(imports)
    cells.append(function_definition)
    cells.append(function_call)
    return cells


def _find_node(node_name: str, pipelines: _ProjectPipelines) -> Node:
    for pipeline in pipelines.values():
        try:
            found_node: Node = pipeline.filter(node_names=[node_name]).nodes[0]
            return found_node
        except ValueError:
            continue
    # If reached the node was not found in the project
    raise ValueError(
        f"Node with name='{node_name}' not found in any pipelines. Remember to specify the node name, not the node function."
    )


def _prepare_imports(node_func: Callable) -> str:
    """Prepare the import statements for loading a node."""
    python_file = inspect.getsourcefile(node_func)
    logger.info(f"Loading node definition from {python_file}")

    # Confirm source file was found
    if python_file: