CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-sphinx-autobuild

Rebuild Sphinx documentation on changes, with hot reloading in the browser.

Overview
Eval results
Files

utils.mddocs/

Utility Functions

Helper functions for port management, browser automation, and formatted console output. These utilities support the core functionality with common operations needed across the sphinx-autobuild system.

Capabilities

Port Management

Find available network ports for the development server.

def find_free_port():
    """
    Find and return a free port number.
    
    Uses socket binding to discover available ports on the local machine.
    The port is immediately released after discovery, so there's a small
    race condition window where another process could claim it.
    
    Returns:
    - int - Available port number (typically in ephemeral range 32768-65535)
    
    Raises:
    - OSError - If no ports are available or socket operations fail
    
    Implementation:
    - Creates socket with SO_REUSEADDR option
    - Binds to ('', 0) to let OS assign free port
    - Returns the assigned port number
    - Socket is automatically closed via context manager
    """

Usage Examples:

from sphinx_autobuild.utils import find_free_port

# Get any available port
port = find_free_port()
print(f"Using port: {port}")  # e.g., "Using port: 54321"

# Use in server configuration
if args.port == 0:
    port = find_free_port()
else:
    port = args.port

Browser Automation

Automatically open web browsers to view documentation.

def open_browser(url_host: str, delay: float) -> None:
    """
    Open browser to specified URL after delay.
    
    Launches the system default browser in a separate thread to avoid
    blocking the main application. The delay allows the server to fully
    start before the browser attempts to connect.
    
    Parameters:
    - url_host: str - Host and port in format "host:port" (e.g., "127.0.0.1:8000")
    - delay: float - Delay in seconds before opening browser
    
    Returns:
    - None
    
    Side Effects:
    - Creates and starts background thread for browser launching
    - Thread sleeps for specified delay then opens browser
    - Uses webbrowser.open() with full HTTP URL
    - Thread is joined (blocks until browser launch completes)
    
    Error Handling:
    - webbrowser.open() failures are handled by webbrowser module
    - Thread exceptions are not propagated to caller
    """

Usage Examples:

from sphinx_autobuild.utils import open_browser

# Open browser immediately
open_browser("127.0.0.1:8000", 0)

# Open browser after 5 second delay (typical)
open_browser("localhost:8080", 5.0)

# Open browser for external access
open_browser("192.168.1.100:3000", 2.5)

# Integration with command line
if args.open_browser:
    open_browser(url_host, args.delay)

Console Output

Formatted console messages with colors and consistent styling.

def show_message(context: str, /) -> None:
    """
    Show message with colored formatting.
    
    Displays informational messages with consistent sphinx-autobuild branding
    and cyan-colored text for easy identification in console output.
    
    Parameters:
    - context: str - Message text to display
    
    Returns:
    - None
    
    Side Effects:
    - Prints to stdout with color formatting
    - Uses colorama for cross-platform color support
    - Format: "[sphinx-autobuild] {cyan_text}{reset}"
    """

def show_command(command: list[str] | tuple[str, ...], /) -> None:
    """
    Show command with colored formatting.
    
    Displays commands that are about to be executed with consistent formatting
    and blue-colored text. Uses shlex.join() for proper shell quoting.
    
    Parameters:
    - command: list[str] | tuple[str, ...] - Command as sequence of arguments
    
    Returns:
    - None
    
    Raises:
    - AssertionError - If command is not list or tuple
    
    Side Effects:
    - Prints to stdout with color formatting
    - Format: "[sphinx-autobuild] > {blue_command}{reset}"
    - Properly quotes arguments with spaces or special characters
    """

Usage Examples:

from sphinx_autobuild.utils import show_message, show_command

# Status messages
show_message("Starting initial build")
show_message("Waiting to detect changes...")
show_message("Server ceasing operations. Cheerio!")

# Command execution display
show_command(["python", "-m", "sphinx", "docs", "_build/html"])
show_command(["echo", "Build complete"])
show_command(["find", ".", "-name", "*.py", "-exec", "echo", "{}", ";"])

# Output examples:
# [sphinx-autobuild] Starting initial build
# [sphinx-autobuild] > python -m sphinx docs _build/html
# [sphinx-autobuild] > echo "Build complete"
# [sphinx-autobuild] > find . -name '*.py' -exec echo '{}' ';'

Internal Implementation Details

Color Management

Uses colorama for cross-platform color support:

from colorama import Fore, Style

# Internal color function
def _log(text, *, colour):
    print(f"{Fore.GREEN}[sphinx-autobuild] {colour}{text}{Style.RESET_ALL}")

# Color assignments
show_message: colour=Fore.CYAN    # Cyan for informational messages
show_command: colour=Fore.BLUE    # Blue for command display

Thread Management

Browser opening uses thread-based delay:

import threading
import time
import webbrowser

def open_browser(url_host: str, delay: float) -> None:
    def _opener():
        time.sleep(delay)                    # Blocking delay in thread
        webbrowser.open(f"http://{url_host}")  # System browser launch
    
    t = threading.Thread(target=_opener)
    t.start()    # Start background thread
    t.join()     # Wait for completion (browser launch)

Command Formatting

Uses shlex for proper shell command formatting:

import shlex

def show_command(command):
    assert isinstance(command, (list, tuple))
    msg = f"> {shlex.join(command)}"    # Proper shell quoting
    _log(msg, colour=Fore.BLUE)

Integration Examples

With Build System

from sphinx_autobuild.utils import show_message, show_command
from sphinx_autobuild.build import Builder

class CustomBuilder(Builder):
    def __call__(self, *, changed_paths):
        if changed_paths:
            show_message(f"Detected changes in {len(changed_paths)} files")
        
        show_message("Starting build process")
        show_command(["python", "-m", "sphinx"] + self.sphinx_args)
        
        # Execute build...
        
        show_message(f"Serving on {self.uri}")

With Server Startup

from sphinx_autobuild.utils import find_free_port, open_browser, show_message

def start_server(args):
    # Port selection
    if args.port == 0:
        port = find_free_port()
        show_message(f"Using automatically selected port: {port}")
    else:
        port = args.port
    
    url_host = f"{args.host}:{port}"
    
    # Browser automation
    if args.open_browser:
        show_message(f"Will open browser in {args.delay} seconds")
        open_browser(url_host, args.delay)
    
    show_message(f"Starting server on {url_host}")
    # Start server...

With Command Execution

from sphinx_autobuild.utils import show_command, show_message
import subprocess

def run_pre_build_commands(commands):
    for command in commands:
        show_message("Running pre-build command")
        show_command(command)
        
        try:
            subprocess.run(command, check=True)
            show_message("Pre-build command completed successfully")
        except subprocess.CalledProcessError as e:
            show_message(f"Pre-build command failed with exit code {e.returncode}")

Platform Compatibility

Color Support

  • Windows: colorama automatically initializes Windows console color support
  • macOS/Linux: Native ANSI color sequence support
  • CI/CD: Colors automatically disabled in non-TTY environments

Browser Opening

  • Windows: Uses default application associations
  • macOS: Uses open command via webbrowser module
  • Linux: Uses desktop environment's default browser (xdg-open, etc.)

Port Discovery

  • All Platforms: Uses standard socket operations
  • IPv4: Binds to all interfaces ("") for maximum compatibility
  • Port Ranges: OS assigns from available ephemeral port range

Error Scenarios

Port Discovery Failures

from sphinx_autobuild.utils import find_free_port

try:
    port = find_free_port()
except OSError as e:
    print(f"Could not find free port: {e}")
    # Fallback to default port or exit

Browser Launch Failures

# Browser opening failures are handled internally by webbrowser module
# No exceptions are raised to the caller
open_browser("127.0.0.1:8000", 5)  # Always succeeds (may fail silently)

Color Display Issues

# Colors automatically disabled in non-TTY environments
# colorama handles platform-specific color support
show_message("This message")  # Colors work where supported, plain text elsewhere

Install with Tessl CLI

npx tessl i tessl/pypi-sphinx-autobuild

docs

build.md

cli.md

filtering.md

index.md

middleware.md

server.md

utils.md

tile.json