code: def run_notebook(notebook_path):
      
      dirname, __ = os.path.split(notebook_path)
      os.chdir(dirname)
      with tempfile.NamedTemporaryFile(suffix=".ipynb") as fout:
          args = ["jupyter-nbconvert", "--to", "notebook", "--execute", "--allow-errors",
            "--ExecutePreprocessor.timeout=300",
            "--output", fout.name, notebook_path]
          try:
              subprocess.check_call(args)
          except subprocess.CalledProcessError as e:
              if e.returncode == 1:
                # print the message and ignore error with code 1 as this indicates there were errors in the notebook
                print(e.output)
                pass
              else:
                # all other codes indicate some other problem, rethrow
                raise
  
          fout.seek(0)
          nb = nbformat.read(fout, nbformat.current_nbformat)
  
      errors = [output for cell in nb.cells if "outputs" in cell
                       for output in cell["outputs"]\
                       if output.output_type == "error"]
  
      return nb, errors
docs: Execute a notebook via nbconvert and collect output.
         :returns (parsed nb object, execution errors)