API Documentation for Python Projects with focus on simplicity and automatic HTML generation from docstrings
—
Built-in HTTP server for documentation development with live reloading and automatic regeneration on source changes. Provides a complete development environment for iterating on documentation.
HTTP server specifically designed for serving pdoc-generated documentation with development features.
class DocServer(http.server.HTTPServer):
"""
pdoc's live-reloading web server.
Features:
- Automatic documentation regeneration on source changes
- Live reloading in browser
- Static file serving for templates and assets
- Error handling and debugging support
"""
all_modules: AllModules
def __init__(self, addr: tuple[str, int], specs: list[str], **kwargs):
"""
Initialize documentation server.
Parameters:
- addr: tuple[str, int] - Server address (host, port)
- specs: list[str] - Module specifications to document
- **kwargs: Additional server configuration options
"""
@cache
def render_search_index(self) -> str:
"""
Render the search index. For performance reasons this is always cached.
Returns:
- str: JavaScript search index for client-side search
"""Specialized request handler for documentation serving with live reload support.
class DocHandler(http.server.BaseHTTPRequestHandler):
"""
HTTP request handler for documentation pages.
Handles:
- Documentation page requests
- Static asset serving (CSS, JS, images)
- Error page generation
- Search index serving
"""
server: DocServer
def do_HEAD(self): ...
def do_GET(self): ...
def handle_request(self) -> str: ...System for tracking all modules and their documentation state.
class AllModules(Mapping[str, doc.Module]):
"""
A lazy-loading implementation of all_modules.
Behaves like a regular dict, but modules are only imported on demand
for performance reasons.
"""
def __init__(self, allowed_modules: Iterable[str]): ...
def __len__(self) -> int: ...
def __iter__(self) -> Iterator[str]: ...
def __contains__(self, item): ...
def __getitem__(self, item: str): ...Utility for launching web browsers and opening documentation.
def open_browser(url: str) -> bool:
"""
Open a URL in a browser window.
In contrast to webbrowser.open, limits the list of suitable browsers.
Gracefully degrades to a no-op on headless servers.
Parameters:
- url: str - URL to open in browser
Returns:
- bool: True if a browser has been opened, False otherwise
"""from pdoc.web import DocServer, open_browser
import threading
# Start documentation server
server_addr = ("localhost", 8080)
server = DocServer(server_addr, modules=["my_package"])
# Open browser in background
browser_thread = threading.Thread(
target=open_browser,
args=[f"http://{server_addr[0]}:{server_addr[1]}"]
)
browser_thread.daemon = True
browser_thread.start()
# Serve documentation with live reload
print(f"Serving documentation at http://{server_addr[0]}:{server_addr[1]}")
server.serve_forever()from pdoc.web import DocServer
from pdoc import render
# Configure rendering for development
render.configure(
docformat="google",
show_source=True,
math=True,
template_directory="./custom_templates"
)
# Create server with custom settings
server = DocServer(
addr=("0.0.0.0", 3000), # Bind to all interfaces
modules=["core", "plugins", "utils"],
watch_paths=["./src", "./templates"], # Additional paths to watch
reload_delay=0.5 # Delay before regeneration
)
try:
print("Documentation server running on http://localhost:3000")
server.serve_forever()
except KeyboardInterrupt:
print("Server stopped")from pdoc.web import DocServer, AllModules
# Track multiple related modules
all_modules = AllModules()
all_modules.add_modules([
"my_project.core",
"my_project.plugins",
"my_project.utils",
"my_project.tests"
])
# Start server with module tracking
server = DocServer(
addr=("localhost", 8000),
all_modules=all_modules,
enable_search=True,
auto_reload=True
)
server.serve_forever()from pdoc.web import DocServer
from pdoc import render
import logging
# Configure for production-like output
render.configure(
docformat="restructuredtext",
show_source=False,
math=True,
mermaid=True,
minify_html=True
)
# Enable detailed logging
logging.basicConfig(level=logging.INFO)
# Server with production settings
server = DocServer(
addr=("localhost", 8080),
modules=["my_package"],
auto_reload=False, # Disable auto-reload for performance
enable_search=True,
gzip_compression=True
)
print("Production-mode development server")
server.serve_forever()import subprocess
import time
from pdoc.web import DocServer
from pathlib import Path
class BuildAwareDocServer:
"""Documentation server that integrates with build tools"""
def __init__(self, modules, build_command=None):
self.modules = modules
self.build_command = build_command
self.server = None
def run_build(self):
"""Run build command before regenerating docs"""
if self.build_command:
print(f"Running build: {self.build_command}")
result = subprocess.run(self.build_command, shell=True)
if result.returncode != 0:
print("Build failed, skipping documentation update")
return False
return True
def start_server(self):
"""Start server with build integration"""
# Initial build
if not self.run_build():
return
# Custom DocServer that runs builds
self.server = DocServer(
addr=("localhost", 8080),
modules=self.modules,
pre_render_hook=self.run_build
)
self.server.serve_forever()
# Usage
build_server = BuildAwareDocServer(
modules=["my_package"],
build_command="npm run build" # or "make", "poetry build", etc.
)
build_server.start_server()from pdoc.web import DocServer
import json
class LiveReloadDocServer(DocServer):
"""Extended server with custom live reload features"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.websocket_clients = set()
def notify_clients(self, event_type="reload", data=None):
"""Send live reload notifications to connected clients"""
message = json.dumps({
"type": event_type,
"data": data or {},
"timestamp": time.time()
})
# Send to all connected WebSocket clients
for client in self.websocket_clients.copy():
try:
client.send(message)
except:
# Remove disconnected clients
self.websocket_clients.discard(client)
def on_file_change(self, file_path):
"""Handle file system changes"""
print(f"File changed: {file_path}")
# Regenerate documentation
self.regenerate_docs()
# Notify browsers to reload
self.notify_clients("reload", {"file": str(file_path)})
# Usage
live_server = LiveReloadDocServer(
addr=("localhost", 8080),
modules=["my_package"]
)
live_server.serve_forever()The web server is typically used through pdoc's command line interface:
# Start development server
pdoc my_package --host localhost --port 8080
# Server with custom options
pdoc my_package --host 0.0.0.0 --port 3000 --math --show-source
# Multiple modules with live reload
pdoc core plugins utils --host localhost --port 8000The server monitors these file types for changes:
.py): Triggers documentation regeneration.jinja2, .html): Updates template cache.css, .js): Refreshes browser cacheInstall with Tessl CLI
npx tessl i tessl/pypi-pdoc