pywebdavserver
A WebDAV server with pluggable storage backends - support for local filesystem and Drime Cloud storage.
Features
-
Multiple Storage Backends:
- Local Filesystem (default): Standard filesystem-based WebDAV access
- Drime Cloud (optional): Access Drime Cloud storage via WebDAV
-
Full WebDAV Support:
- Read and write files
- Create and delete folders
- Move and copy resources
- File locking for collaborative editing
- WebDAV properties
- Directory browser
-
Flexible Authentication:
- Optional HTTP Basic/Digest authentication
- Anonymous access support
- Per-server credentials
-
Easy Configuration:
- Named backend configurations (rclone-style) - no more CLI flag overload!
- Simple CLI with sensible defaults
- Programmatic API for custom integrations
- SSL/TLS support
- Secure password obscuring (rclone-compatible)
Installation
Basic Installation (Local Filesystem Only)
pip install pywebdavserver
With Drime Cloud Support
pip install pywebdavserver[drime]
Full Installation (with config encryption)
pip install pywebdavserver[drime]
pip install cryptography # For password obscuring
Development Installation
git clone <repository>
cd pywebdavserver
pip install -e ".[dev,drime]"
Quick Start
Using Named Backend Configurations (Recommended)
The best way to use pywebdavserver is with named backend configurations - similar to how rclone works:
# Add a backend configuration (interactive wizard)
pywebdavserver config add drime-personal
# Start server with the configured backend
pywebdavserver --backend drime-personal --no-auth
# List all configured backends
pywebdavserver config list
# Show backend details
pywebdavserver config show drime-personal
# Remove a backend
pywebdavserver config remove drime-personal
Benefits:
- No need to remember API keys or workspace IDs
- Passwords are securely obscured in config file
- Easily switch between multiple cloud accounts
- Clean CLI without flag overload
- Ready for future cloud providers (Nextcloud, S3, etc.)
Local Filesystem Backend
Start a WebDAV server with local filesystem storage:
# Anonymous access (no authentication)
pywebdavserver --no-auth
# With authentication
pywebdavserver --username admin --password secret
# Custom path and port
pywebdavserver --path /data/webdav --port 9000 --no-auth
# Read-only mode
pywebdavserver --readonly --no-auth
# With SSL/TLS
pywebdavserver --ssl-cert cert.pem --ssl-key key.pem --no-auth
# Or configure a named backend
pywebdavserver config add local-docs
# Then start with: pywebdavserver --backend local-docs --no-auth
Drime Cloud Backend
# Method 1: Using named backend (recommended)
pywebdavserver config add drime-work
pywebdavserver --backend drime-work --no-auth
# Method 2: Using environment variables (legacy)
export DRIME_API_KEY="your-api-key-here"
pywebdavserver --backend drime --workspace-id 0 --no-auth
Backend Configuration
Configuration File Location
Backend configurations are stored in TOML format at:
- Linux/macOS:
~/.config/pywebdavserver/backends.toml - Windows:
%USERPROFILE%\.config\pywebdavserver\backends.toml
Config Commands
# Interactive wizard to add a backend
pywebdavserver config add <name>
# List all backends
pywebdavserver config list
# Show backend details (with obscured passwords)
pywebdavserver config show <name>
# Show backend details (reveal passwords)
pywebdavserver config show <name> --reveal-passwords
# Remove a backend
pywebdavserver config remove <name>
# Get config file path
pywebdavserver config path
# Edit config file manually
pywebdavserver config edit
# Obscure a password for manual editing
pywebdavserver config obscure
# Or from stdin: echo "mypassword" | pywebdavserver config obscure -
# Reveal an obscured password
pywebdavserver config reveal <obscured-password>
Example Configuration File
# ~/.config/pywebdavserver/backends.toml
[local-docs]
type = "local"
path = "/home/user/Documents"
readonly = false
[local-readonly]
type = "local"
path = "/mnt/shared"
readonly = true
[drime-personal]
type = "drime"
api_key = "FZq5EuI..." # Obscured with AES-CTR encryption
workspace_id = 0
readonly = false
cache_ttl = 30.0
max_file_size = 524288000
[drime-work]
type = "drime"
api_key = "zEYAL3o..." # Different workspace, different key
workspace_id = 42
readonly = false
cache_ttl = 60.0
max_file_size = 1073741824
Password Obscuring
Passwords are automatically obscured when using pywebdavserver config add. The
obscuring uses AES-CTR encryption (compatible with rclone's obscure command).
This is NOT secure encryption! It's designed to prevent casual "shoulder surfing" -
anyone with access to the code can decrypt the passwords. For true security, use file
system permissions (chmod 600 ~/.config/pywebdavserver/backends.toml).
Mounting the WebDAV Server
macOS (Finder)
- Open Finder
- Go → Connect to Server (⌘K)
- Enter:
http://localhost:8080 - Click Connect
Linux
# Install davfs2
sudo apt-get install davfs2 # Debian/Ubuntu
sudo yum install davfs2 # RHEL/CentOS
# Mount
sudo mount -t davfs http://localhost:8080 /mnt/webdav
Windows
- Right-click "This PC"
- Select "Map network drive..."
- Enter:
http://localhost:8080 - Click Finish
CLI Reference
Usage: pywebdavserver [OPTIONS]
PyWebDAV Server - WebDAV server with pluggable storage backends.
Options:
--backend [local|drime] Storage backend (default: local)
--path PATH Root directory for local backend
(default: /tmp/webdav)
--host TEXT Host address (default: 127.0.0.1)
--port INTEGER Port number (default: 8080)
--username TEXT WebDAV username
--password TEXT WebDAV password
--readonly Enable read-only mode
--cache-ttl FLOAT Cache TTL for Drime backend (default: 30.0)
--max-file-size INTEGER Max file size in bytes (default: 524288000)
--workspace-id INTEGER Workspace ID for Drime (default: 0)
--ssl-cert PATH SSL certificate file
--ssl-key PATH SSL private key file
-v, --verbose Increase verbosity (can repeat)
--no-auth Disable authentication
--version Show version and exit
--help Show this message and exit
Programmatic Usage
Local Filesystem Provider
from pywebdavserver.providers.local import LocalStorageProvider
from pywebdavserver.server import run_webdav_server
# Create provider
provider = LocalStorageProvider(
root_path="/data/webdav",
readonly=False
)
# Run server
run_webdav_server(
provider=provider,
host="0.0.0.0",
port=8080,
username="admin",
password="secret",
verbose=2
)
Drime Cloud Provider
from pydrime.api import DrimeClient
from pywebdavserver.providers.drime import DrimeDAVProvider
from pywebdavserver.server import run_webdav_server
# Create Drime client
client = DrimeClient(email="user@example.com", password="password")
# Create provider
provider = DrimeDAVProvider(
client=client,
workspace_id=0,
readonly=False,
cache_ttl=30.0,
max_file_size=500 * 1024 * 1024
)
# Run server
run_webdav_server(
provider=provider,
host="0.0.0.0",
port=8080,
username="admin",
password="secret",
verbose=2
)
Custom WSGI Integration
from pywebdavserver.providers.local import LocalStorageProvider
from pywebdavserver.server import create_webdav_app
provider = LocalStorageProvider("/data/webdav")
app = create_webdav_app(
provider=provider,
username="admin",
password="secret",
verbose=1
)
# Use with any WSGI server (gunicorn, uWSGI, etc.)
Architecture
Storage Provider Interface
The StorageProvider base class defines the interface for storage backends. Each
provider must:
- Inherit from
wsgidav.dav_provider.DAVProvider - Implement WebDAV resource operations (get, list, create, delete, move, copy)
- Provide metadata (size, modified time, ETags)
- Support locking (optional but recommended)
Available Providers
LocalStorageProvider
- Backend: Local filesystem
- Dependencies: None (uses wsgidav's FilesystemProvider)
- Features: Standard filesystem WebDAV access
- Use Case: Simple file sharing, local development
DrimeDAVProvider
- Backend: Drime Cloud API
- Dependencies:
pydrime>=0.1.0 - Features: Cloud storage, eventual consistency handling, caching
- Use Case: Cloud file access, team collaboration
Configuration Examples
Development Server
# Quick local testing
pywebdavserver --no-auth --verbose
Production Server
# Secure production setup
pywebdavserver \
--path /var/www/webdav \
--host 0.0.0.0 \
--port 443 \
--ssl-cert /etc/ssl/certs/server.crt \
--ssl-key /etc/ssl/private/server.key \
--username webdav \
--password $(cat /etc/webdav/password) \
--readonly
Drime Cloud Gateway
# Expose Drime workspace via WebDAV
export DRIME_EMAIL="admin@company.com"
export DRIME_PASSWORD="$(cat ~/.drime/password)"
pywebdavserver \
--backend drime \
--workspace-id 123 \
--host 0.0.0.0 \
--port 8080 \
--username teamlead \
--password teampass \
--cache-ttl 60
Troubleshooting
Connection Refused
- Check if the server is running:
netstat -an | grep 8080 - Verify firewall settings
- Try binding to
0.0.0.0instead of127.0.0.1
Authentication Fails
- Ensure username and password are provided together
- Check WebDAV client supports Basic/Digest auth
- Try without authentication first (
--no-auth)
Drime Backend Errors
- Verify
DRIME_EMAILandDRIME_PASSWORDenvironment variables - Check network connectivity to Drime Cloud
- Ensure
pydrimeis installed:pip install pywebdavserver[drime]
File Locking Issues
- File locking requires a writable lock storage
- Check directory permissions
- Increase cache TTL for better lock handling
Development
Running Tests
pip install -e ".[dev]"
pytest tests/
Code Formatting
ruff check .
ruff format .
Building Documentation
# This README serves as the main documentation
Comparison with Other WebDAV Servers
| Feature | pywebdavserver | Apache mod_dav | WsgiDAV CLI |
|---|---|---|---|
| Local Filesystem | ✅ | ✅ | ✅ |
| Cloud Storage | ✅ (Drime) | ❌ | ❌ |
| Python API | ✅ | ❌ | ⚠️ (Limited) |
| File Locking | ✅ | ✅ | ✅ |
| Easy Setup | ✅ | ⚠️ (Complex) | ✅ |
| Pluggable Backends | ✅ | ❌ | ⚠️ (Limited) |
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
License
MIT License - see LICENSE file for details.
Credits
Support
For issues and questions:
- GitHub Issues: /issues
- Documentation: This README
- WsgiDAV Docs: https://wsgidav.readthedocs.io/
Changelog
See CHANGELOG.md for version history.
Metadata
Release files for pywebdavserver 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pywebdavserver-0.1.2.tar.gz | 61.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pywebdavserver-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 101.6 kB
Release files / pywebdavserver-0.1.2.tar.gz
| Download URL | pywebdavserver-0.1.2.tar.gz |
|---|---|
| Size | 61.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
77d1984e99b076faded30c108ee0cf25b08d27d7c36f7cfd0eb6d50f60ba1288
|
|
BLAKE2b-256 checksum How to use checksums |
b907666f03377d81203bfacc4b531e4ad9af4ce0af566fbc91a7ea03cd1b1445
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.25
|
Release files / pywebdavserver-0.1.2-py3-none-any.whl
| Download URL | pywebdavserver-0.1.2-py3-none-any.whl |
|---|---|
| Size | 39.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5581aab37c43660ecd2a99ac4ee1f73f1100c87f1a1808d87a7384756f91003d
|
|
BLAKE2b-256 checksum How to use checksums |
614fd3065ed1ca64f012b69a4a0504763b0d402225e36a98d61893c4aa1d2142
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.25
|