def METHOD_NAME(directory: str, blocks: List[Block]) -> List[str]:
    """
    Execute the code blocks embedded in a tutorial
    :param directory:
    :param blocks:
    :return: errors
    """
    Path(directory).mkdir(parents=True, exist_ok=True)
    logging.info(f"Executing in: {directory}")
    last_block = None
    errs = []
    def err(e):
        errs.append(e)
        logging.error(e)
    for block in blocks:
        write_lines(block.prior_lines)
        logging.info(f"# Block: {block.category} {block.title}")
        if block.is_file_block():
            path = PurePath(directory, block.title)
            with open(path, "w", encoding="UTF-8") as stream:
                stream.write(block.content)
        elif block.is_bash():
            if "no_execute" in block.annotations:
                continue
            cmd = block.content.strip().split()
            if ">" in cmd:
                # redirects not support in subprocess.run
                pos = cmd.index(">")
                outpath = cmd[pos + 1 :]
                cmd = cmd[0:pos]
                if len(outpath) > 1:
                    raise Exception(f"Maximum 1 token after > in {block.content}. Got: {outpath}")
                outpath = str(Path(directory, *outpath))
                logging.info(f"OUTPATH = {outpath}")
            else:
                outpath = None
            logging.info(f"Executing: {cmd}")
            r = subprocess.run(cmd, cwd=directory, capture_output=True)
            block.output = r.stdout.decode("utf-8")
            if outpath:
                with open(outpath, "w", encoding="UTF-8") as stream:
                    logging.info(f"WRITING {len(block.output)} TO = {outpath}")
                    stream.write(block.output)
            block.error = r.stderr.decode("utf-8")
            logging.info(f"OUT [sample] = {block.output[0:30]}")
            if block.expected_fail:
                if r.returncode == 0:
                    err(f"Command unexpectedly succeeded: {cmd}")
                else:
                    logging.info("Failed as expected")
                if block.error:
                    logging.info(f"ERR [sample] = ...{block.error[-200:]}")
            else:
                if block.error:
                    logging.info(f"ERR = {block.error}")
                if r.returncode != 0:
                    err(f"Command failed: {cmd}")
                else:
                    logging.info("Success!")
        elif block.is_stdout():
            if "compare_rdf" in block.annotations:
                logging.warning(
                    "SKIPPING RDF COMPARISON. TODO: https://github.com/linkml/linkml/issues/427"
                )
            elif last_block.output:
                if last_block.output.strip() != block.content.strip():
                    err(f"Mismatch: {str(last_block.output)} != {block.content}")
                else:
                    logging.info("Hurray! Contents match!")
            else:
                logging.info("No comparison performed")
        else:
            logging.warning(f"Ignoring block: {block}")
        last_block = block
    return errs