CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pydoc-markdown

Create Python API documentation in Markdown format

Pending
Overview
Eval results
Files

utility-functions.mddocs/

Utility Functions

Helper functions and classes for common operations including docspec manipulation, template processing, file watching, and page management.

Capabilities

Docspec Utilities

Functions for working with docspec objects and API analysis.

def get_members_of_type(objs: Union[docspec.ApiObject, List[docspec.ApiObject]], type_: Type[T]) -> List[T]:
    """
    Get all members of specified type from API objects.
    
    Args:
        objs: Single API object or list of API objects to search
        type_: Type to filter for (e.g., docspec.Function, docspec.Class)
        
    Returns:
        List of objects matching the specified type
    """

def format_function_signature(func: docspec.Function, exclude_self: bool = False) -> str:
    """
    Format function signature with arguments and return type.
    
    Args:
        func: Function object to format
        exclude_self: Whether to exclude 'self' parameter from signature
        
    Returns:
        Formatted signature string like "(arg1, arg2) -> ReturnType"
    """

def is_function(obj: docspec.ApiObject) -> TypeGuard[docspec.Function]:
    """
    Type guard to check if object is a function.
    
    Args:
        obj: API object to check
        
    Returns:
        True if object is a docspec.Function
    """

def is_method(obj: docspec.ApiObject) -> TypeGuard[docspec.Function]:
    """
    Type guard to check if object is a method (function inside a class).
    
    Args:
        obj: API object to check
        
    Returns:
        True if object is a method
    """

def is_property(obj: docspec.ApiObject) -> TypeGuard[docspec.Function]:
    """
    Type guard to check if object is a property (function with @property decorator).
    
    Args:
        obj: API object to check
        
    Returns:
        True if object is a property
    """

def is_attr(obj: docspec.ApiObject) -> TypeGuard[docspec.Variable]:
    """
    Type guard to check if object is a class attribute.
    
    Args:
        obj: API object to check
        
    Returns:
        True if object is a class attribute
    """

def get_object_description(obj: docspec.ApiObject) -> str:
    """
    Get descriptive text for an API object.
    
    Args:
        obj: API object to describe
        
    Returns:
        Description like "module", "class", "function", "method", etc.
    """

ApiSuite Wrapper

Wrapper class for working with collections of API objects.

class ApiSuite:
    """
    Wrapper for API object collections with utility methods.
    
    Provides convenient access to docspec objects with type filtering,
    relationship analysis, and other collection operations.
    """
    
    def get_members_of_type(self, type_: Type[T]) -> List[T]:
        """
        Get all members of specified type from the suite.
        
        Args:
            type_: Type to filter for
            
        Returns:
            List of objects matching the specified type
        """

Template Processing

YAML template loading with variable substitution.

def load(filename: str, context: Dict[str, Any]) -> Any:
    """
    Load YAML template file with variable substitution.
    
    Args:
        filename: Path to YAML template file
        context: Dictionary of variables for substitution
        
    Returns:
        Parsed YAML data with variables substituted
    """

class Attributor:
    """
    Attribute accessor for template variables.
    
    Provides dot-notation access to dictionary data for use in templates.
    """
    
    def __init__(self, data: Dict[str, Any]):
        """
        Initialize with data dictionary.
        
        Args:
            data: Dictionary to provide attribute access for
        """
    
    def __getattr__(self, name: str) -> Any:
        """
        Get attribute value from underlying data.
        
        Args:
            name: Attribute name to access
            
        Returns:
            Value from data dictionary
            
        Raises:
            AttributeError: If attribute not found
        """

File Watching

File system monitoring for development workflows.

def watch_paths(paths: List[str]) -> Tuple[Observer, Event]:
    """
    Set up file system watching for specified paths.
    
    Args:
        paths: List of file/directory paths to watch for changes
        
    Returns:
        Tuple of (Observer, Event) where Event is set when changes occur
    """

Page Management

Utilities for managing documentation pages and collections.

def collect_pages(directory: str, pattern: str = "*.md") -> List[str]:
    """
    Collect documentation pages from directory.
    
    Args:
        directory: Directory to search for pages
        pattern: File pattern to match (default: "*.md")
        
    Returns:
        List of page file paths
    """

Markdown Utilities

Text processing utilities for Markdown generation.

def escape_except_blockquotes(text: str) -> str:
    """
    Escape Markdown special characters except in blockquotes.
    
    Args:
        text: Text to escape
        
    Returns:
        Text with Markdown characters escaped appropriately
    """

Helper Functions

Additional utility functions for common operations.

def dotted_name(obj: docspec.ApiObject) -> str:
    """
    Get fully qualified dotted name for an API object.
    
    Args:
        obj: API object to get name for
        
    Returns:
        Dotted name like "module.Class.method"
    """

Usage Examples

Docspec Object Analysis

from pydoc_markdown.util.docspec import get_members_of_type, is_method, format_function_signature
import docspec

# Get all functions from modules
modules = config.load_modules()
all_functions = get_members_of_type(modules, docspec.Function)

# Filter for methods only
methods = [f for f in all_functions if is_method(f)]

# Format signatures
for method in methods:
    signature = format_function_signature(method, exclude_self=True)
    print(f"{method.name}{signature}")

API Object Type Checking

from pydoc_markdown.util.docspec import is_function, is_method, is_property, is_attr

for obj in module.members:
    if is_function(obj):
        if is_method(obj):
            print(f"Method: {obj.name}")
        elif is_property(obj):
            print(f"Property: {obj.name}")
        else:
            print(f"Function: {obj.name}")
    elif is_attr(obj):
        print(f"Attribute: {obj.name}")

Template Processing

from pydoc_markdown.util.ytemplate import load, Attributor
import os

# Load template with environment variables
context = {"env": Attributor(os.environ)}
config_data = load("pydoc-markdown.yml.template", context)

# Template file might contain:
# loaders:
#   - type: python
#     modules: ["{{ env.PACKAGE_NAME }}"]

File Watching for Development

from pydoc_markdown.util.watchdog import watch_paths
import time

# Watch source files for changes
source_files = ["src/mypackage/", "docs/"]
observer, event = watch_paths(source_files)

try:
    while True:
        if event.wait(timeout=1.0):
            print("Files changed, regenerating docs...")
            # Regenerate documentation
            event.clear()
        else:
            time.sleep(0.1)
finally:
    observer.stop()

Page Collection

from pydoc_markdown.util.pages import collect_pages

# Collect all markdown files in docs directory
doc_pages = collect_pages("docs/", "*.md")

# Collect specific patterns
api_pages = collect_pages("docs/api/", "*.md")
examples = collect_pages("examples/", "*.py")

Markdown Text Processing

from pydoc_markdown.util.misc import escape_except_blockquotes

# Safely escape markdown while preserving blockquotes
text = """
This text has *special* characters that need escaping.

> But this blockquote should remain unchanged
> with its *formatting* intact.
"""

escaped = escape_except_blockquotes(text)

Object Path and Naming

from pydoc_markdown.contrib.renderers.markdown import dotted_name

# Get full dotted names for API objects
for obj in module.members:
    full_name = dotted_name(obj)
    print(f"Full name: {full_name}")
    # Output: "mypackage.MyClass.my_method"

Integration Examples

Custom Processor Using Utilities

from pydoc_markdown.interfaces import Processor
from pydoc_markdown.util.docspec import get_members_of_type, is_method
import docspec

class MethodDocumentationProcessor(Processor):
    def process(self, modules: List[docspec.Module], resolver: Optional[Resolver]) -> None:
        # Get all methods across all modules
        methods = get_members_of_type(modules, docspec.Function)
        methods = [m for m in methods if is_method(m)]
        
        # Add standard documentation for undocumented methods
        for method in methods:
            if not method.docstring:
                signature = format_function_signature(method, exclude_self=True)
                method.docstring = f"Method {method.name}{signature}"

Custom Renderer Using Utilities

from pydoc_markdown.interfaces import Renderer
from pydoc_markdown.util.docspec import get_object_description, dotted_name
from pydoc_markdown.util.misc import escape_except_blockquotes

class CustomTableRenderer(Renderer):
    def render(self, modules: List[docspec.Module]) -> None:
        with open("api-table.md", "w") as f:
            f.write("# API Reference Table\n\n")
            f.write("| Name | Type | Description |\n")
            f.write("|------|------|-------------|\n")
            
            for module in modules:
                for obj in module.members:
                    name = dotted_name(obj)
                    obj_type = get_object_description(obj)
                    desc = obj.docstring or "No description"
                    desc = escape_except_blockquotes(desc.split('\n')[0])  # First line only
                    
                    f.write(f"| {name} | {obj_type} | {desc} |\n")

Development Workflow Integration

from pydoc_markdown.util.watchdog import watch_paths
from pydoc_markdown.util.pages import collect_pages
from pydoc_markdown import PydocMarkdown

class DocumentationWatcher:
    def __init__(self, config_file: str):
        self.config_file = config_file
        self.config = PydocMarkdown()
        self.config.load_config(config_file)
    
    def start_watching(self):
        # Collect all relevant files to watch
        source_files = []
        
        # Add Python source files
        for loader in self.config.loaders:
            if hasattr(loader, 'search_path'):
                source_files.extend(loader.search_path)
        
        # Add documentation files
        doc_files = collect_pages("docs/", "*.md")
        source_files.extend(doc_files)
        
        # Add config file
        source_files.append(self.config_file)
        
        # Start watching
        observer, event = watch_paths(source_files)
        
        try:
            while True:
                if event.wait(timeout=2.0):
                    print("Changes detected, regenerating documentation...")
                    self.regenerate_docs()
                    event.clear()
        finally:
            observer.stop()
    
    def regenerate_docs(self):
        modules = self.config.load_modules()
        self.config.process(modules)
        self.config.render(modules)

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