Пример #1
0
    def handle_request(self) -> Optional[str]:
        """Actually handle a request. Called by `do_HEAD` and `do_GET`."""
        path = self.path.split("?", 1)[0]

        if path == "/":
            out = render.html_index(self.server.all_modules)
        else:
            module = removesuffix(path.lstrip("/"), ".html").replace("/", ".")
            if module not in self.server.all_modules:
                self.send_response(404)
                self.send_header("content-type", "text/html")
                self.end_headers()
                return render.html_error(error=f"Module {module!r} not found")

            mtime = ""
            t = extract.module_mtime(module)
            if t:
                mtime = f"{t:.1f}"
            if "mtime=1" in self.path:
                self.send_response(200)
                self.send_header("content-type", "text/plain")
                self.end_headers()
                return mtime

            try:
                extract.invalidate_caches(module)
                mod = doc.Module(extract.load_module(module))
            except Exception:
                self.send_response(500)
                self.send_header("content-type", "text/html")
                self.end_headers()
                return render.html_error(
                    error=f"Error importing {module!r}",
                    details=traceback.format_exc(),
                )
            out = render.html_module(
                module=mod,
                all_modules=self.server.all_modules,
                mtime=mtime,
            )

        self.send_response(200)
        self.send_header("content-type", "text/html")
        self.end_headers()
        return out
Пример #2
0
def pdoc(
    *modules: Union[Path, str],
    output_directory: Optional[Path] = None,
    format: Literal["html"] = "html",
) -> str:
    """
    Render the documentation for a list of modules.

     - If `output_directory` is `None`, returns the rendered documentation
       for the first module in the list.
     - If `output_directory` is set, recursively writes the rendered output
       for all specified modules and their submodules to the target destination.

    Rendering options can be configured by calling `pdoc.render.configure` in advance.
    """
    retval = io.StringIO()
    if output_directory:

        def write(mod: doc.Module):
            assert output_directory
            outfile = output_directory / f"{mod.fullname.replace('.', '/')}.html"
            outfile.parent.mkdir(parents=True, exist_ok=True)
            outfile.write_bytes(r(mod).encode())

    else:

        def write(mod: doc.Module):
            retval.write(r(mod))

    all_modules = extract.parse_specs(modules)

    if format == "html":

        def r(mod: doc.Module) -> str:
            return render.html_module(module=mod, all_modules=all_modules)

    elif format == "markdown":  # pragma: no cover
        raise NotImplementedError(
            "Markdown support is currently unimplemented, but PRs are welcome!"
        )
    elif format == "repr":
        r = render.repr_module
    else:
        raise ValueError(f"Invalid rendering format {format!r}.")

    for mod in all_modules:
        try:
            m = extract.load_module(mod)
        except RuntimeError:
            warnings.warn(f"Error importing {mod}:\n{traceback.format_exc()}",
                          RuntimeWarning)
        else:
            write(doc.Module(m))

        if not output_directory:
            return retval.getvalue()

    assert output_directory

    if format == "html":
        index = render.html_index(all_modules)
        if index:
            (output_directory / "index.html").write_bytes(index.encode())

    return retval.getvalue()