Installation
Requirements
Python ≥ 3.14
A supported async database driver (see below)
Installing OpenViper
Install from PyPI using pip:
pip install openviper
Optional Extras
OpenViper ships optional feature sets as pip extras:
Development Extras
Additional extras for contributing to OpenViper or building documentation:
Extra |
Install command |
Installs |
|---|---|---|
|
|
|
|
|
|
Note
The backup-db and restore-db management commands are included in the
core package and do not require a separate install.
Multiple extras can be combined:
pip install openviper[postgres,tasks-redis]
Database Configuration
OpenViper uses a DATABASES dictionary in settings.py:
DATABASES = {
"default": {
"BACKEND": "openviper.db.backends.DefaultDatabaseBackend",
"OPTIONS": {
"URL": "sqlite+aiosqlite:///./db.sqlite3",
"ECHO": False,
"POOL_SIZE": 20,
"MAX_OVERFLOW": 80,
"POOL_RECYCLE": 900,
"POOL_TIMEOUT": 10,
},
},
}
For PostgreSQL:
DATABASES = {
"default": {
"BACKEND": "openviper.db.backends.DefaultDatabaseBackend",
"OPTIONS": {
"URL": "postgresql+asyncpg://user:pass@localhost:5432/mydb",
"POOL_SIZE": 20,
"MAX_OVERFLOW": 80,
"POOL_RECYCLE": 900,
"POOL_TIMEOUT": 10,
"PREPARED_STMT_CACHE": 256,
},
},
}
The BACKEND key is optional. When omitted, OpenViper uses the default
DefaultDatabaseBackend (SQLAlchemy async engine). The short name
"sqlalchemy" is also accepted as an alias for
"openviper.db.backends.DefaultDatabaseBackend".
Configuration keys can be placed either inside OPTIONS (nested format)
or directly in the alias dict (flat format). Both are valid:
# Nested format (recommended):
DATABASES = {
"default": {
"OPTIONS": {"URL": "postgresql+asyncpg://user:pass@localhost/db"},
},
}
# Flat format (also supported):
DATABASES = {
"default": {
"URL": "postgresql+asyncpg://user:pass@localhost/db",
},
}
Pool options:
Key |
Default |
Range |
Description |
|---|---|---|---|
|
20 |
1-100 |
Number of persistent connections in the pool. |
|
80 |
0-200 |
Additional connections allowed beyond |
|
900 |
60-86400 |
Recycle connections after this many seconds. |
|
10 |
1-300 |
Seconds to wait for a connection from the pool. |
|
256 |
0-2048 |
asyncpg prepared-statement cache size (PostgreSQL only). |
|
False |
Echo all SQL statements to the log. |
Supported URL formats:
Database |
URL format |
|---|---|
SQLite (dev) |
|
PostgreSQL |
|
MariaDB / MySQL |
|
Custom database backends can be registered by dotted path:
DATABASES = {
"default": {
"BACKEND": "myapp.db.MyCustomBackend",
"OPTIONS": {"URL": "custom://host/db"},
},
}
Message Broker Configuration
Background tasks require a message broker supported by Dramatiq. OpenViper supports Redis, RabbitMQ, Amazon SQS, and PostgreSQL.
Redis
Install Redis:
sudo apt install redis # Linux (Debian/Ubuntu)
brew install redis # macOS
sudo dnf install redis # Fedora
Then set the broker and URL in settings.py:
TASKS: dict[str, Any] = dataclasses.field(
default_factory=lambda: {
"enabled": 1,
"broker": "redis",
"broker_url": os.environ.get("REDIS_URL", "redis://localhost:6379/0"),
"backend_url": "",
"logging": {
"level": "INFO",
"file": {
"log_dir": "logs",
"file_name": "tasks.log",
"log_format": "json",
"max_size": 10,
},
"database": {
"task": 1,
"periodic": 1,
},
},
}
)
RabbitMQ
Install RabbitMQ:
sudo apt install rabbitmq-server # Linux (Debian/Ubuntu)
brew install rabbitmq # macOS
sudo dnf install rabbitmq-server # Fedora
Then set the broker and URL in settings.py:
TASKS: dict[str, Any] = dataclasses.field(
default_factory=lambda: {
"enabled": 1,
"broker": "rabbitmq",
"broker_url": os.environ.get("AMQP_URL", "amqp://guest:guest@localhost:5672"),
"backend_url": "",
"logging": {
"level": "INFO",
"file": {
"log_dir": "logs",
"file_name": "tasks.log",
"log_format": "json",
"max_size": 10,
},
"database": {
"task": 1,
"periodic": 1,
},
},
}
)
Note
The backend_url key enables result retrieval (e.g., fetching an
actor’s return value). This currently requires a Redis URL regardless
of which broker is selected.
Amazon SQS
Install the SQS extra:
pip install 'openviper[tasks-sqs]'
Configure in settings.py:
TASKS: dict[str, Any] = dataclasses.field(
default_factory=lambda: {
"enabled": 1,
"broker": "sqs",
"broker_url": "",
"sqs_namespace": "myapp",
"sqs_endpoint_url": os.environ.get("SQS_ENDPOINT_URL", ""),
"backend_url": "",
"logging": {
"level": "INFO",
"file": {
"log_dir": "logs",
"file_name": "tasks.log",
"log_format": "json",
"max_size": 10,
},
"database": {
"task": 1,
"periodic": 1,
},
},
}
)
Note
SQS uses AWS credentials configured via the standard boto3
credential chain (environment variables, IAM roles, etc.). Set
sqs_endpoint_url to use with ElasticMQ for local development.
Stub (Testing)
The stub broker processes messages in-process without any external dependency, making it ideal for unit and integration tests. No extra package is required - it ships with Dramatiq itself.
Configure in settings.py or your test configuration:
TASKS: dict[str, Any] = dataclasses.field(
default_factory=lambda: {
"enabled": 1,
"broker": "stub",
"backend_url": "",
"logging": {
"level": "INFO",
"file": {
"log_dir": "logs",
"file_name": "tasks.log",
"log_format": "json",
"max_size": 10,
},
"database": {
"task": 1,
"periodic": 1,
},
},
}
)
Note
The stub broker does not require a broker_url. It should only
be used in testing environments, not in production.
Cache
Configure caching in settings.py using the CACHES dictionary:
CACHES = {
"default": {
"BACKEND": "openviper.cache.RedisCache",
"OPTIONS": {"host": "localhost", "port": 6379, "db": 0},
},
}
For local development, the default InMemoryCache requires no
configuration:
CACHES = {
"default": {
"BACKEND": "openviper.cache.InMemoryCache",
"OPTIONS": {"ttl": 300},
},
}
Verifying the Installation
After installing, the openviper CLI should be available:
openviper version # OpenViper 0.1.1
You can also verify from Python:
import openviper print(openviper.__version__) # 0.1.1
Development Server
OpenViper ships with Uvicorn as its ASGI server. Start the development server with either:
# Via management command (from inside a project)
python viperctl.py start-server --reload # --host 127.0.0.1 --port 8000
See also
See the Uvicorn and Gunicorn documentation for production-grade deployment configuration.
Set OPENVIPER_ENV=production before starting the server. OpenViper
validates the settings at startup and rejects insecure configurations:
export OPENVIPER_ENV=production
export SECRET_KEY="$(python -c 'import secrets; print(secrets.token_urlsafe(64))')"
python viperctl.py start-server
Required production settings:
DEBUGmust beFalseSECRET_KEYmust be set to a strong random value (>= 50 chars)SECURE_COOKIESmust beTrueSECURE_SSL_REDIRECTmust beTrueSECURE_HSTS_SECONDSmust be >= 31536000 (1 year)SESSION_COOKIE_SECUREmust beTrueCSRF_COOKIE_SECUREmust beTrueOPENAPI["enabled"]should beFalseCORS_ALLOWED_HEADERSmust not be wildcard ("*")
If any check fails, SettingsValidationError is raised at startup.