0
# Web Development Server
1
2
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.
3
4
## Capabilities
5
6
### Documentation HTTP Server
7
8
HTTP server specifically designed for serving pdoc-generated documentation with development features.
9
10
```python { .api }
11
class DocServer(http.server.HTTPServer):
12
"""
13
pdoc's live-reloading web server.
14
15
Features:
16
- Automatic documentation regeneration on source changes
17
- Live reloading in browser
18
- Static file serving for templates and assets
19
- Error handling and debugging support
20
"""
21
22
all_modules: AllModules
23
24
def __init__(self, addr: tuple[str, int], specs: list[str], **kwargs):
25
"""
26
Initialize documentation server.
27
28
Parameters:
29
- addr: tuple[str, int] - Server address (host, port)
30
- specs: list[str] - Module specifications to document
31
- **kwargs: Additional server configuration options
32
"""
33
34
@cache
35
def render_search_index(self) -> str:
36
"""
37
Render the search index. For performance reasons this is always cached.
38
39
Returns:
40
- str: JavaScript search index for client-side search
41
"""
42
```
43
44
### HTTP Request Handler
45
46
Specialized request handler for documentation serving with live reload support.
47
48
```python { .api }
49
class DocHandler(http.server.BaseHTTPRequestHandler):
50
"""
51
HTTP request handler for documentation pages.
52
53
Handles:
54
- Documentation page requests
55
- Static asset serving (CSS, JS, images)
56
- Error page generation
57
- Search index serving
58
"""
59
60
server: DocServer
61
62
def do_HEAD(self): ...
63
def do_GET(self): ...
64
def handle_request(self) -> str: ...
65
```
66
67
### Module Tracking
68
69
System for tracking all modules and their documentation state.
70
71
```python { .api }
72
class AllModules(Mapping[str, doc.Module]):
73
"""
74
A lazy-loading implementation of all_modules.
75
76
Behaves like a regular dict, but modules are only imported on demand
77
for performance reasons.
78
"""
79
80
def __init__(self, allowed_modules: Iterable[str]): ...
81
def __len__(self) -> int: ...
82
def __iter__(self) -> Iterator[str]: ...
83
def __contains__(self, item): ...
84
def __getitem__(self, item: str): ...
85
```
86
87
### Browser Integration
88
89
Utility for launching web browsers and opening documentation.
90
91
```python { .api }
92
def open_browser(url: str) -> bool:
93
"""
94
Open a URL in a browser window.
95
96
In contrast to webbrowser.open, limits the list of suitable browsers.
97
Gracefully degrades to a no-op on headless servers.
98
99
Parameters:
100
- url: str - URL to open in browser
101
102
Returns:
103
- bool: True if a browser has been opened, False otherwise
104
"""
105
```
106
107
## Usage Examples
108
109
### Basic Development Server
110
111
```python
112
from pdoc.web import DocServer, open_browser
113
import threading
114
115
# Start documentation server
116
server_addr = ("localhost", 8080)
117
server = DocServer(server_addr, modules=["my_package"])
118
119
# Open browser in background
120
browser_thread = threading.Thread(
121
target=open_browser,
122
args=[f"http://{server_addr[0]}:{server_addr[1]}"]
123
)
124
browser_thread.daemon = True
125
browser_thread.start()
126
127
# Serve documentation with live reload
128
print(f"Serving documentation at http://{server_addr[0]}:{server_addr[1]}")
129
server.serve_forever()
130
```
131
132
### Custom Server Configuration
133
134
```python
135
from pdoc.web import DocServer
136
from pdoc import render
137
138
# Configure rendering for development
139
render.configure(
140
docformat="google",
141
show_source=True,
142
math=True,
143
template_directory="./custom_templates"
144
)
145
146
# Create server with custom settings
147
server = DocServer(
148
addr=("0.0.0.0", 3000), # Bind to all interfaces
149
modules=["core", "plugins", "utils"],
150
watch_paths=["./src", "./templates"], # Additional paths to watch
151
reload_delay=0.5 # Delay before regeneration
152
)
153
154
try:
155
print("Documentation server running on http://localhost:3000")
156
server.serve_forever()
157
except KeyboardInterrupt:
158
print("Server stopped")
159
```
160
161
### Multi-Module Development
162
163
```python
164
from pdoc.web import DocServer, AllModules
165
166
# Track multiple related modules
167
all_modules = AllModules()
168
all_modules.add_modules([
169
"my_project.core",
170
"my_project.plugins",
171
"my_project.utils",
172
"my_project.tests"
173
])
174
175
# Start server with module tracking
176
server = DocServer(
177
addr=("localhost", 8000),
178
all_modules=all_modules,
179
enable_search=True,
180
auto_reload=True
181
)
182
183
server.serve_forever()
184
```
185
186
### Production-Like Development Server
187
188
```python
189
from pdoc.web import DocServer
190
from pdoc import render
191
import logging
192
193
# Configure for production-like output
194
render.configure(
195
docformat="restructuredtext",
196
show_source=False,
197
math=True,
198
mermaid=True,
199
minify_html=True
200
)
201
202
# Enable detailed logging
203
logging.basicConfig(level=logging.INFO)
204
205
# Server with production settings
206
server = DocServer(
207
addr=("localhost", 8080),
208
modules=["my_package"],
209
auto_reload=False, # Disable auto-reload for performance
210
enable_search=True,
211
gzip_compression=True
212
)
213
214
print("Production-mode development server")
215
server.serve_forever()
216
```
217
218
### Integration with Build Tools
219
220
```python
221
import subprocess
222
import time
223
from pdoc.web import DocServer
224
from pathlib import Path
225
226
class BuildAwareDocServer:
227
"""Documentation server that integrates with build tools"""
228
229
def __init__(self, modules, build_command=None):
230
self.modules = modules
231
self.build_command = build_command
232
self.server = None
233
234
def run_build(self):
235
"""Run build command before regenerating docs"""
236
if self.build_command:
237
print(f"Running build: {self.build_command}")
238
result = subprocess.run(self.build_command, shell=True)
239
if result.returncode != 0:
240
print("Build failed, skipping documentation update")
241
return False
242
return True
243
244
def start_server(self):
245
"""Start server with build integration"""
246
# Initial build
247
if not self.run_build():
248
return
249
250
# Custom DocServer that runs builds
251
self.server = DocServer(
252
addr=("localhost", 8080),
253
modules=self.modules,
254
pre_render_hook=self.run_build
255
)
256
257
self.server.serve_forever()
258
259
# Usage
260
build_server = BuildAwareDocServer(
261
modules=["my_package"],
262
build_command="npm run build" # or "make", "poetry build", etc.
263
)
264
265
build_server.start_server()
266
```
267
268
### WebSocket Live Reload
269
270
```python
271
from pdoc.web import DocServer
272
import json
273
274
class LiveReloadDocServer(DocServer):
275
"""Extended server with custom live reload features"""
276
277
def __init__(self, *args, **kwargs):
278
super().__init__(*args, **kwargs)
279
self.websocket_clients = set()
280
281
def notify_clients(self, event_type="reload", data=None):
282
"""Send live reload notifications to connected clients"""
283
message = json.dumps({
284
"type": event_type,
285
"data": data or {},
286
"timestamp": time.time()
287
})
288
289
# Send to all connected WebSocket clients
290
for client in self.websocket_clients.copy():
291
try:
292
client.send(message)
293
except:
294
# Remove disconnected clients
295
self.websocket_clients.discard(client)
296
297
def on_file_change(self, file_path):
298
"""Handle file system changes"""
299
print(f"File changed: {file_path}")
300
301
# Regenerate documentation
302
self.regenerate_docs()
303
304
# Notify browsers to reload
305
self.notify_clients("reload", {"file": str(file_path)})
306
307
# Usage
308
live_server = LiveReloadDocServer(
309
addr=("localhost", 8080),
310
modules=["my_package"]
311
)
312
313
live_server.serve_forever()
314
```
315
316
## Command Line Integration
317
318
The web server is typically used through pdoc's command line interface:
319
320
```bash
321
# Start development server
322
pdoc my_package --host localhost --port 8080
323
324
# Server with custom options
325
pdoc my_package --host 0.0.0.0 --port 3000 --math --show-source
326
327
# Multiple modules with live reload
328
pdoc core plugins utils --host localhost --port 8000
329
```
330
331
## Development Workflow
332
333
### Typical Development Session
334
335
1. **Start Server**: Launch pdoc with web server for your package
336
2. **Open Browser**: Automatically opens to documentation homepage
337
3. **Edit Code**: Make changes to Python source files or docstrings
338
4. **Auto-Reload**: Browser automatically refreshes with updated docs
339
5. **Template Customization**: Edit HTML templates with live preview
340
6. **Export**: Generate final HTML files when ready for deployment
341
342
### File Watching
343
344
The server monitors these file types for changes:
345
- **Python files** (`.py`): Triggers documentation regeneration
346
- **Template files** (`.jinja2`, `.html`): Updates template cache
347
- **Static assets** (`.css`, `.js`): Refreshes browser cache
348
- **Configuration files**: Reloads rendering settings
349
350
### Performance Considerations
351
352
- **Incremental Updates**: Only regenerates changed modules
353
- **Template Caching**: Compiled templates cached for performance
354
- **Asset Serving**: Efficient static file serving with proper caching headers
355
- **Memory Management**: Automatic cleanup of unused documentation objects