CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pydoc-markdown

Create Python API documentation in Markdown format

Pending
Overview
Eval results
Files

plugin-interfaces.mddocs/

Plugin Interfaces

Abstract interfaces and base classes that define the plugin architecture for loaders, processors, renderers, and additional functionality like source linking and development servers.

Capabilities

Core Interfaces

Base interfaces that form the foundation of pydoc-markdown's plugin system.

class Context:
    """
    Context data passed to plugins during initialization.
    
    Attributes:
        directory: Working directory for plugin operations
    """
    directory: str
    
    def __init__(self, directory: str) -> None:
        """
        Initialize context with working directory.
        
        Args:
            directory: Working directory path
        """

class PluginBase(ABC):
    """
    Abstract base class for all pydoc-markdown plugins.
    
    Provides basic plugin lifecycle management.
    """
    
    def init(self, context: Context) -> None:
        """
        Initialize plugin with context data.
        
        Args:
            context: Context containing directory and other initialization data
        """

Loader Interface

Interface for loading documentation data from various sources.

class Loader(PluginBase):
    """
    Interface for loading documentation data.
    
    Loaders extract API information from source code, documentation files,
    or other sources and convert them into docspec.Module objects.
    """
    
    def load(self) -> Iterable[docspec.Module]:
        """
        Load documentation data.
        
        Returns:
            Iterable of docspec.Module objects containing API information
            
        Raises:
            LoaderError: If loading fails
        """

class LoaderError(Exception):
    """Exception raised when loader operations fail."""

Processor Interface

Interface for transforming and enhancing loaded documentation data.

class Processor(PluginBase):
    """
    Interface for processing and transforming docspec.Module objects.
    
    Processors typically modify docstrings, filter content, resolve references,
    or apply other transformations to prepare data for rendering.
    """
    
    def process(self, modules: List[docspec.Module], resolver: Optional[Resolver]) -> None:
        """
        Process modules in place.
        
        Args:
            modules: List of modules to process (modified in place)
            resolver: Optional resolver for handling cross-references
        """

Renderer Interface

Interface for generating documentation output in various formats.

class Renderer(PluginBase):
    """
    Interface for rendering docspec.Module objects to output files.
    
    Renderers generate final documentation in formats like Markdown, HTML,
    or integration with static site generators.
    """
    
    def process(self, modules: List[docspec.Module], resolver: Optional[Resolver]) -> None:
        """
        Optional processing step before rendering.
        
        Args:
            modules: List of modules to process
            resolver: Optional resolver for cross-references
        """
    
    def get_resolver(self, modules: List[docspec.Module]) -> Optional[Resolver]:
        """
        Get resolver for cross-reference handling.
        
        Args:
            modules: List of modules for resolver context
            
        Returns:
            Resolver instance or None if not supported
        """
    
    def render(self, modules: List[docspec.Module]) -> None:
        """
        Render modules to output format.
        
        Args:
            modules: List of modules to render
        """

Resolver Interfaces

Interfaces for resolving cross-references between API objects.

class Resolver(ABC):
    """
    Interface for resolving cross-references to hyperlinks.
    
    Used by processors to convert references in docstrings to URLs or other
    link formats appropriate for the target documentation format.
    """
    
    def resolve_ref(self, scope: docspec.ApiObject, ref: str) -> Optional[str]:
        """
        Resolve reference to a hyperlink.
        
        Args:
            scope: API object containing the reference
            ref: Reference string to resolve
            
        Returns:
            Resolved hyperlink or None if resolution fails
        """

class ResolverV2(ABC):
    """
    New-style resolver interface that returns resolved objects directly.
    
    Provides more flexibility than the original Resolver interface by
    returning the actual resolved API object instead of a string representation.
    """
    
    def resolve_reference(self, suite: ApiSuite, scope: docspec.ApiObject, ref: str) -> Optional[docspec.ApiObject]:
        """
        Resolve reference to an API object.
        
        Args:
            suite: API suite containing all available objects
            scope: API object containing the reference
            ref: Reference string to resolve
            
        Returns:
            Resolved API object or None if resolution fails
        """

Additional Renderer Interfaces

Specialized renderer interfaces for specific rendering capabilities.

class SinglePageRenderer(PluginBase):
    """
    Interface for renderers that can generate single-page output.
    """
    
    def render_single_page(
        self, 
        fp: TextIO, 
        modules: List[docspec.Module], 
        page_title: Optional[str] = None
    ) -> None:
        """
        Render modules to a single page.
        
        Args:
            fp: File object to write output to
            modules: List of modules to render
            page_title: Optional title for the page
        """

class SingleObjectRenderer(PluginBase):
    """
    Interface for renderers that can render individual API objects.
    """
    
    def render_object(self, fp: TextIO, obj: docspec.ApiObject, options: Dict[str, Any]) -> None:
        """
        Render a single API object.
        
        Args:
            fp: File object to write output to
            obj: API object to render
            options: Rendering options and configuration
        """

Server Interface

Interface for development server functionality.

class Server(ABC):
    """
    Interface for development server capabilities.
    
    Renderers implementing this interface can provide live preview
    functionality with automatic reloading when source files change.
    """
    
    def get_server_url(self) -> str:
        """
        Get the development server URL.
        
        Returns:
            URL where the development server is accessible
        """
    
    def start_server(self) -> subprocess.Popen:
        """
        Start the development server process.
        
        Returns:
            Process handle for the running server
        """
    
    def reload_server(self, process: subprocess.Popen) -> subprocess.Popen:
        """
        Reload server process when files change.
        
        Args:
            process: Current server process
            
        Returns:
            New server process or same process if reload not needed
        """

Builder Interface

Interface for build functionality after rendering.

class Builder(ABC):
    """
    Interface for renderers that support building final output.
    
    Builders can generate final static sites, optimize output,
    or perform other post-rendering operations.
    """
    
    def build(self, site_dir: str) -> None:
        """
        Build final output after rendering.
        
        Args:
            site_dir: Directory where build output should be placed
        """

Source Linker Interface

Interface for linking documentation to source code.

class SourceLinker(PluginBase):
    """
    Interface for generating links to source code.
    
    Source linkers determine URLs to the original source code for
    API objects, enabling documentation to include "view source" links.
    """
    
    def get_source_url(self, obj: docspec.ApiObject) -> Optional[str]:
        """
        Get URL to source code for an API object.
        
        Args:
            obj: API object to get source URL for
            
        Returns:
            URL to source code or None if not available
        """

Plugin Implementation Examples

Custom Loader Example

from pydoc_markdown.interfaces import Loader, Context
import docspec

class CustomLoader(Loader):
    def __init__(self, source_path: str):
        self.source_path = source_path
    
    def init(self, context: Context) -> None:
        # Initialize with context
        self.working_dir = context.directory
    
    def load(self) -> Iterable[docspec.Module]:
        # Load from custom source
        module = docspec.Module(
            name="custom_module",
            location=docspec.Location("custom.py", 1),
            docstring="Custom loaded module"
        )
        return [module]

Custom Processor Example

from pydoc_markdown.interfaces import Processor, Resolver
import docspec

class CustomProcessor(Processor):
    def __init__(self, transform_pattern: str):
        self.transform_pattern = transform_pattern
    
    def process(self, modules: List[docspec.Module], resolver: Optional[Resolver]) -> None:
        for module in modules:
            for obj in module.members:
                if obj.docstring:
                    # Apply custom transformation
                    obj.docstring = obj.docstring.replace(
                        self.transform_pattern, 
                        "**" + self.transform_pattern + "**"
                    )

Custom Renderer Example

from pydoc_markdown.interfaces import Renderer, Resolver
import docspec

class CustomRenderer(Renderer):
    def __init__(self, output_file: str):
        self.output_file = output_file
    
    def render(self, modules: List[docspec.Module]) -> None:
        with open(self.output_file, 'w') as f:
            for module in modules:
                f.write(f"# {module.name}\n\n")
                if module.docstring:
                    f.write(f"{module.docstring}\n\n")
                
                for obj in module.members:
                    f.write(f"## {obj.name}\n\n")
                    if obj.docstring:
                        f.write(f"{obj.docstring}\n\n")

Custom Source Linker Example

from pydoc_markdown.interfaces import SourceLinker
import docspec

class GitHubSourceLinker(SourceLinker):
    def __init__(self, repo_url: str, branch: str = "main"):
        self.repo_url = repo_url.rstrip('/')
        self.branch = branch
    
    def get_source_url(self, obj: docspec.ApiObject) -> Optional[str]:
        if obj.location and obj.location.filename:
            return f"{self.repo_url}/blob/{self.branch}/{obj.location.filename}#L{obj.location.lineno}"
        return None

Plugin Registration

Plugins are typically registered via entry points in setup.py or pyproject.toml:

Poetry Configuration (pyproject.toml)

[tool.poetry.plugins."pydoc_markdown.interfaces.Loader"]
custom = "mypackage.loaders:CustomLoader"

[tool.poetry.plugins."pydoc_markdown.interfaces.Processor"]  
custom = "mypackage.processors:CustomProcessor"

[tool.poetry.plugins."pydoc_markdown.interfaces.Renderer"]
custom = "mypackage.renderers:CustomRenderer"

[tool.poetry.plugins."pydoc_markdown.interfaces.SourceLinker"]
custom = "mypackage.linkers:CustomSourceLinker"

Using Custom Plugins

# pydoc-markdown.yml
loaders:
  - type: custom
    source_path: "/path/to/source"

processors:
  - type: custom
    transform_pattern: "TODO"

renderer:
  type: custom
  output_file: "custom-docs.md"

Interface Compatibility

Multiple Interface Implementation

Renderers can implement multiple interfaces for enhanced functionality:

class AdvancedRenderer(Renderer, Server, Builder, SinglePageRenderer):
    def render(self, modules: List[docspec.Module]) -> None:
        # Standard rendering
        pass
    
    def get_server_url(self) -> str:
        return "http://localhost:8000"
    
    def start_server(self) -> subprocess.Popen:
        # Start development server
        pass
    
    def build(self, site_dir: str) -> None:
        # Build final output
        pass
    
    def render_single_page(self, fp: TextIO, modules: List[docspec.Module], page_title: Optional[str] = None) -> None:
        # Single page rendering
        pass

Interface Detection

Check renderer capabilities at runtime:

from pydoc_markdown.interfaces import Server, Builder

# Check if renderer supports server
if isinstance(renderer, Server):
    server_url = renderer.get_server_url()
    process = renderer.start_server()

# Check if renderer supports building
if isinstance(renderer, Builder):
    renderer.build("/path/to/site/")

Install with Tessl CLI

npx tessl i tessl/pypi-pydoc-markdown

docs

cli-interface.md

docstring-processing.md

documentation-rendering.md

index.md

main-config.md

plugin-interfaces.md

python-loading.md

utility-functions.md

tile.json