API reference rendering is broken

Goal state

  • Correctly render docstrings in Docusaurus.
  • We use Google style.
  • Types should be rendered from type annotations (not docstrings).

Checklist

  • Functions & methods input arguments
  • Objects attributes
  • Class attributes
  • Properties of Pydantic models, data classes, and maybe typed dicts
  • Inherit docstrings from base classes
  • Inline kwargs unpack
  • Rendered return type is clickable

Functions & methods input arguments

  • Render docstrings of functions and methods arguments.
def foo(
    self,
    a: str | None = None,
    *,
    b: bool = True,
) -> int:
    """Blah blah blah.

    Args:
        a: I am docstring of a input argument.
        b: I am docstring of b input argument.
    """
  • There is only one option and it works.

Objects attributes

  • Render docstrings of object attributes.
class A:
    """Blah blah blah.

    Attributes:
        b: I am docstring of b attribute (1).
    """

    def __init__(self, b: int) -> None:
        self.b = b
        """I am docstring of b attribute as well (2)."""

    @property
    def c(self) -> int:
        "I am docstring of c attribute. (3)"  # works
        return self.b + 1
  • Current state:
    • (1) does not work
    • (2) does not work
    • (3) works
  • Goal state:
    • Either (1) or (2) should be rendered in the same way as (3).

Class attributes

  • Render docstrings of (public) class attributes.
class A:
    """Blah blah blah.

    Attributes:
        B: I am docstring of B attribute (1).
    """

    B = 1
    """I am docstring of a class attribute (2)."""
  • Current state:
    • (1) does not work
    • (2) works
  • Goal state:
    • This is OK.

Properties of Pydantic models, data classes, and maybe typed dicts

  • How we should document them to be rendered (Args vs Attributes)?
  • For example:
from pyndatic import BaseModel


class Configuration(BaseModel):
    """Configuration of the Crawler."""

    internal_timeout: Annotated[timedelta | None, Field(alias='crawlee_internal_timeout')] = None
    """Timeout for internal operations such as marking a request as processed."""

    verbose_log: Annotated[bool, Field(alias='crawlee_verbose_log')] = False
    """Allows verbose logging."""

Inherit docstrings from base classes

For example:

class MemoryStorageClient(BaseStorageClient):
    # Class docstring is inherited from BaseStorageClient.

    @override
    def dataset(self, id: str) -> DatasetClient:
        # Method docstring is inherited from `BaseStorageClient.dataset`.
        return DatasetClient(
            memory_storage_client=self,
            id=id,
        )

Inline kwargs unpack

  • It should list all arguments, including the kwargs unpack (defined as typed dict).
class HttpCrawler(BasicCrawler):
    def __init__(
        self,
        blah: Iterable[int] = (),
        **kwargs: Unpack[BasicCrawlerOptions],
    ) -> None:
        # List of all args is `blah` and all from kwargs.

Rendered return type is clickable