DevServer¶
The DevServer class provides a development server with hot reload functionality. It automatically restarts your application when Python source files are modified, making development faster and more convenient.
Module: wiverno.dev.dev_server¶
Overview¶
DevServer is specifically designed for development environments and includes:
- Hot Reload - Automatically restarts when
.pyfiles change - Debouncing - Prevents excessive restarts by grouping changes
- File Watching - Uses watchdog to monitor specified directories
- Rich UI - Beautiful console output with progress indicators
- Configurable Ignoring - Exclude specific files/directories from watching
⚠️ Important: DevServer is for development only. Do not use in production!
Constructor¶
DevServer(app_module, app_name="app", host="localhost", port=8000, watch_dirs=None, ignore_patterns=None, debounce_seconds=1.0)¶
Creates a new development server instance.
Parameters:
app_module(str): Module path containing the WSGI application (e.g.,'run','myapp.main')app_name(str, optional): Name of the application variable in the module. Defaults to"app"host(str, optional): Server host address. Defaults to"localhost"port(int, optional): Server port. Defaults to8000watch_dirs(list[str], optional): Directories to watch for changes. If None, watches current directoryignore_patterns(list[str], optional): Patterns to ignore. Defaults to common patterns (see below)debounce_seconds(float, optional): Time to wait before restarting after file changes. Defaults to1.0
Default Ignore Patterns:
__pycache__/.venv/,venv/.git/.pytest_cache/,.mypy_cache/,.ruff_cache/tests/htmlcov/,.coverage
from wiverno.dev.dev_server import DevServer
# Basic usage
server = DevServer(
app_module="myapp",
app_name="app",
host="localhost",
port=8000,
)
Attributes¶
app_module: str¶
Module path containing the WSGI application.
app_name: str¶
Name of the application variable.
server = DevServer(app_module="run", app_name="application")
print(server.app_name) # Output: application
host: str¶
Server host address.
port: int¶
Server port number.
watch_dirs: list[str]¶
List of directories to watch for changes.
server = DevServer(
app_module="run",
watch_dirs=["./myapp", "./shared"],
)
print(server.watch_dirs) # Output: ['./myapp', './shared']
ignore_patterns: list[str]¶
List of patterns to ignore when watching for changes.
server = DevServer(
app_module="run",
ignore_patterns=["__pycache__", "*.pyc", ".venv"],
)
print(server.ignore_patterns)
debounce_seconds: float¶
Time to wait before restarting after file changes.
server = DevServer(app_module="run", debounce_seconds=2.0)
print(server.debounce_seconds) # Output: 2.0
Methods¶
serve(app_module="run", app_name="app", host="localhost", port=8000) [static]¶
Main entry point for running the development server. This is the recommended way to start the server.
Parameters:
app_module(str, optional): Module path containing the WSGI application. Defaults to"run"app_name(str, optional): Name of the application variable. Defaults to"app"host(str, optional): Server host address. Defaults to"localhost"port(int, optional): Server port. Defaults to8000
Returns: None (blocks until interrupted)
from wiverno.dev.dev_server import DevServer
# Quick start
DevServer.serve()
# Custom configuration
DevServer.serve(
app_module="myapp",
app_name="application",
host="0.0.0.0",
port=8080,
)
stop() -> None¶
Stop the development server and file watcher.
Gracefully shuts down the server process and stops file watching.
Usage Examples¶
Quick Start¶
from wiverno.dev.dev_server import DevServer
# Simplest form - uses defaults (run.py with 'app' variable)
DevServer.serve()
Custom Configuration¶
For more detailed examples and project structure, see the Running Guide.
Advanced Configuration¶
from wiverno.dev.dev_server import DevServer
server = DevServer(
app_module="myapp",
app_name="app",
host="0.0.0.0",
port=8000,
watch_dirs=[
"./myapp", # Watch application code
"./shared", # Watch shared utilities
"./config", # Watch configuration
],
ignore_patterns=[
"__pycache__",
"*.pyc",
".venv",
"venv",
"tests",
"*.log",
".git",
],
debounce_seconds=1.5, # Wait 1.5 seconds before restart
)
# Use serve() static method for actual startup
# DevServer.serve(...)
Project Structure Example¶
myproject/
├── myapp/
│ ├── __init__.py
│ ├── main.py # Contains 'app'
│ └── routes.py
├── dev.py # Development server script
└── run.py # Production server script
dev.py:
from wiverno.dev.dev_server import DevServer
if __name__ == "__main__":
DevServer.serve(
app_module="myapp.main",
app_name="app",
host="127.0.0.1",
port=8000,
)
Run with:
Hot Reload in Action¶
When you save a file:
WARNING: File changed: /path/to/myapp/routes.py
>> Server restarting...
╭────────────────────────────────────────╮
│ Wiverno Development Server │
│ │
│ Server: http://localhost:8000 │
│ Debug Mode: ON │
│ Restart: #2 │
│ Press Ctrl+C to stop │
╰────────────────────────────────────────╯
How Hot Reload Works¶
DevServer uses the watchdog library to monitor file changes:
- Monitors
.pyfiles in specified directories - Debounces changes (waits
debounce_secondsbefore restart) - Terminates old process gracefully
- Spawns new process with updated code
See the Running Guide for detailed explanation.
CLI Alternative¶
Use the Wiverno CLI for quick development server starts:
# Start dev server with defaults
wiverno run dev
# Custom configuration
wiverno run dev --host 0.0.0.0 --port 8080
# Specify module and app
wiverno run dev --app-module myapp --app-name application
Best Practices¶
Use for Development Only¶
# ✅ Good - Development
if __name__ == "__main__":
from wiverno.dev.dev_server import DevServer
DevServer.serve()
# ❌ Bad - Don't use in production
if __name__ == "__main__":
from wiverno.dev.dev_server import DevServer
DevServer.serve(host="0.0.0.0") # Exposed to internet!
Configure Ignore Patterns¶
Ignore files that shouldn't trigger restarts:
DevServer.serve(
app_module="myapp",
ignore_patterns=[
"__pycache__",
"*.pyc",
".venv",
"tests", # Don't restart on test changes
"*.log", # Ignore log files
"static/", # Ignore static assets
"migrations/", # Ignore database migrations
],
)
Separate Dev and Production Scripts¶
# dev.py - Development only
from wiverno.dev.dev_server import DevServer
if __name__ == "__main__":
DevServer.serve(app_module="myapp")
# run.py - Production
from wiverno.core.server import RunServer
from myapp import app
if __name__ == "__main__":
server = RunServer(app, host="0.0.0.0", port=8000)
server.start()
Adjust Debounce Time¶
For different workflows:
# Fast restarts (may restart too often)
DevServer.serve(debounce_seconds=0.5)
# Slower restarts (better for large projects)
DevServer.serve(debounce_seconds=2.0)
# Default (recommended)
DevServer.serve(debounce_seconds=1.0)
Troubleshooting¶
Hot Reload Not Working¶
Problem: Files change but server doesn't restart.
Solutions:
- Check file is not in ignore patterns
- Verify file has
.pyextension - Ensure file is in watched directories
- Check console for error messages
# Debug: Print watch directories
server = DevServer(
app_module="myapp",
watch_dirs=["./myapp"], # Explicit watch directory
)
print(f"Watching: {server.watch_dirs}")
Too Many Restarts¶
Problem: Server restarts constantly.
Solutions:
- Increase debounce time
- Add patterns to ignore list
- Check for auto-save or backup files
DevServer.serve(
debounce_seconds=2.0, # Wait longer
ignore_patterns=[
"__pycache__",
"*.swp", # Vim swap files
"*.tmp", # Temp files
"*~", # Backup files
],
)
Import Errors¶
Problem: ImportError: No module named 'myapp'
Solutions:
- Verify module path is correct
- Check PYTHONPATH
- Ensure
__init__.pyexists in package directories
# Wrong
DevServer.serve(app_module="myapp") # Looking for myapp.py
# Correct
DevServer.serve(app_module="myapp.main") # Looking for myapp/main.py
Port Already in Use¶
Problem: OSError: Address already in use
Solutions:
# Find and kill process
lsof -i :8000
kill -9 <PID>
# Or use different port
DevServer.serve(port=8001)
Related Documentation¶
- Running Your Application - Complete guide on development and production servers
- RunServer - Production server documentation
- CLI Commands - Command-line interface
Comparison with RunServer¶
| Feature | DevServer | RunServer |
|---|---|---|
| Hot Reload | ✅ Yes | ❌ No |
| Purpose | Development | Production |
| Performance | Lower | Higher |
| File Watching | ✅ Yes | ❌ No |
| Graceful Shutdown | ✅ Yes | ✅ Yes |
| Dependencies | watchdog, rich | None |
| Use Case | Local development | Production deployment |
Summary¶
- Use
DevServerfor all development work - It automatically restarts when code changes
- Configure ignore patterns to avoid unnecessary restarts
- Never use in production - use RunServer or Gunicorn instead
- Main entry point is
DevServer.serve()static method