<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def generate_pdf(html, *, cache_dir: Path=DFT_CACHE_DIR, grayscale: bool=False, lowquality: bool=False, margin_bottom: str=None, margin_left: str=None, margin_right: str=None, margin_top: str=None, orientation: str=None, page_height: str=None, page_width: str=None, page_size: str=None, image_dpi: str=None, image_quality: str=None, **extra_kwargs):
 """ Generate a pdf from either a url or a html string. After the html and url arguments all other arguments are passed straight to wkhtmltopdf For details on extra arguments see the output of get_help() and get_extended_help() All arguments whether specified or caught with extra_kwargs are converted to command line args with "'--' + original_name.replace('_', '-')" Arguments which are True are passed with no value eg. just --quiet, False and None arguments are missed, everything else is passed with str(value). :param html: html string to generate pdf from :param grayscale: bool :param lowquality: bool :param margin_bottom: string eg. 10mm :param margin_left: string eg. 10mm :param margin_right: string eg. 10mm :param margin_top: string eg. 10mm :param orientation: Portrait or Landscape :param page_height: string eg. 10mm :param page_width: string eg. 10mm :param page_size: string: A4, Letter, etc. :param image_dpi: int default 600 :param image_quality: int default 94 :param extra_kwargs: any exotic extra options for wkhtmltopdf :return: string representing pdf """

    if not cache_dir.exists():
        Path.mkdir(cache_dir)

    py_args = dict(
        cache_dir=cache_dir,
        grayscale=grayscale,
        lowquality=lowquality,
        margin_bottom=margin_bottom,
        margin_left=margin_left,
        margin_right=margin_right,
        margin_top=margin_top,
        orientation=orientation,
        page_height=page_height,
        page_width=page_width,
        page_size=page_size,
        image_dpi=image_dpi,
        image_quality=image_quality,
    )
    py_args.update(extra_kwargs)
    cmd_args = _convert_args(**py_args)

    p = _execute_wk(*cmd_args, input=html.encode())
    pdf_content = p.stdout

    # it seems wkhtmltopdf's error codes can be false, we'll ignore them if we
    # seem to have generated a pdf
    if p.returncode != 0 and pdf_content[:4] != b'%PDF':
        raise RuntimeError('error running wkhtmltopdf, command: {!r}\n'
                           'response: "{}"'.format(cmd_args, p.stderr.decode().strip()))
    return pdf_content