Configuration
The openviper.conf package provides OpenViper’s typed settings system.
Settings are declared as frozen dataclasses, loaded from an environment variable,
and can be overridden by .env files or environment variables at runtime.
Overview
Settings are defined by subclassing Settings and decorating
the subclass with @dataclasses.dataclass(frozen=True). The framework loads
settings from the module pointed to by the OPENVIPER_SETTINGS_MODULE environment
variable.
An alternative programmatic configuration path is available via
settings.configure(obj) for tests and embedded use-cases.
Key Classes & Functions
- class openviper.conf.Settings
Base frozen dataclass for all project settings. Subclass and decorate with
@dataclasses.dataclass(frozen=True)to customise for your project. All fields are immutable after construction.Project
Field
Type
Default / Notes
PROJECT_NAMEstr"OpenViper Application"VERSIONstrFramework version (auto-set)
DEBUGboolTrue— setFalsein productionALLOWED_HOSTStuple[str, ...]("localhost", "127.0.0.1")INSTALLED_APPStuple[str, ...]()— dotted paths to app modulesUSE_TZboolTrueTIME_ZONEstr"UTC"MIDDLEWAREtuple[str, ...]Security, CORS, Session, Auth middleware by default
Admin Panel
Field
Type
Default / Notes
ADMIN_TITLEstr"OpenViper Admin"ADMIN_HEADER_TITLEstr"OpenViper"ADMIN_FOOTER_TITLEstr"OpenViper Admin"Security
Field
Type
Default / Notes
SECRET_KEYstr""— must be set via env var in productionSECURE_SSL_REDIRECTboolFalseSECURE_HSTS_SECONDSint0— seconds for HSTS headerSECURE_HSTS_INCLUDE_SUBDOMAINSboolFalseSECURE_HSTS_PRELOADboolFalseSECURE_COOKIESboolFalseX_FRAME_OPTIONSstr"DENY"SECURE_BROWSER_XSS_FILTERboolTrueSECURE_CONTENT_SECURITY_POLICYdict | NoneNone— CSP header directives dictDatabase
Field
Type
Default / Notes
DATABASE_URLstr""— SQLAlchemy async URL e.g."sqlite+aiosqlite:///db.sqlite3"DATABASE_ECHOboolFalse— log all SQL statementsDATABASE_POOL_SIZEint5DATABASE_MAX_OVERFLOWint10DATABASE_POOL_RECYCLEint3600— seconds before a connection is recycledCache
Field
Type
Default / Notes
CACHE_BACKENDstr"memory"—"memory"or"redis"CACHE_URLstr""— Redis URL when using the Redis backendCACHE_TTLint300— default TTL in secondsAuthentication & Session
Field
Type
Default / Notes
PASSWORD_HASHERStuple[str, ...]("argon2", "bcrypt")SESSION_COOKIE_NAMEstr"sessionid"SESSION_TIMEOUTtimedeltatimedelta(hours=1)SESSION_COOKIE_SECUREboolFalse— setTruein production (requires HTTPS)SESSION_COOKIE_HTTPONLYboolTrue— alwaysTruefor XSS protectionSESSION_COOKIE_SAMESITEstr"Lax"—"Lax","Strict", or"None"SESSION_COOKIE_PATHstr"/"SESSION_COOKIE_DOMAINstr | NoneNone— browser-determined domainUSER_MODELstr"openviper.auth.models.User"AUTH_SESSION_ENABLEDboolTrueSESSION_STOREstr"database"—"database"or a dotted custom pathAUTH_BACKENDStuple[str, ...]JWT + Session backends
DEFAULT_AUTHENTICATION_CLASSEStuple[str, ...]JWTAuthentication,SessionAuthenticationDEFAULT_PERMISSION_CLASSEStuple[str, ...]("openviper.http.permissions.IsAuthenticated",)JWT
Field
Type
Default / Notes
JWT_ALGORITHMstr"HS256"JWT_ACCESS_TOKEN_EXPIREtimedeltatimedelta(minutes=30)JWT_REFRESH_TOKEN_EXPIREtimedeltatimedelta(days=7)CSRF
Field
Type
Default / Notes
CSRF_COOKIE_NAMEstr"csrftoken"CSRF_COOKIE_SECUREboolFalseCSRF_COOKIE_HTTPONLYboolFalse— must beFalsefor double-submit cookie patternCSRF_COOKIE_SAMESITEstr"Lax"CSRF_TRUSTED_ORIGINStuple[str, ...]()CORS
Field
Type
Default / Notes
CORS_ALLOWED_ORIGINStuple[str, ...]()CORS_ALLOW_CREDENTIALSboolFalseCORS_ALLOWED_METHODStuple[str, ...]("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS")CORS_ALLOWED_HEADERStuple[str, ...]("*",)CORS_EXPOSE_HEADERStuple[str, ...]()CORS_MAX_AGEint600— preflight cache in secondsStatic Files & Media
Field
Type
Default / Notes
STATIC_URLstr"/static/"STATIC_ROOTstr"./static/"STATICFILES_DIRStuple[str, ...]("static/",)MEDIA_URLstr"/media/"MEDIA_ROOTstr"./media/"MEDIA_DIRstr"./media/"STATIC_STORAGEstr"local"—"local"or"s3"MEDIA_STORAGEstr"local"MAX_FILE_SIZEint10485760(10 MB)Templates
Field
Type
Default / Notes
TEMPLATES_DIRstr"templates/"TEMPLATE_AUTO_RELOADboolTrueJINJA_PLUGINSdict{}— set{"enable": 1, "path": "jinja_plugins"}to activate auto-discoveryLogging
Field
Type
Default / Notes
LOG_LEVELstr"INFO"LOG_FORMATstr"text"—"text"or"json"Email
Field
Type
Default / Notes
EMAILdictBackend config dict; keys:
backend,host,port,use_tls,use_ssl,timeout,username,password,from,default_sender,fail_silently,use_background_workerRate Limiting
Field
Type
Default / Notes
RATE_LIMIT_BACKENDstr"memory"—"memory"or"redis"RATE_LIMIT_REQUESTSint100RATE_LIMIT_WINDOWint60— window in secondsRATE_LIMIT_BYstr"ip"—"ip","user", or"path"Background Tasks
Field
Type
Default / Notes
TASKSdict{}— Dramatiq broker/worker configurationModel Events
Field
Type
Default / Notes
MODEL_EVENTSdict{}— per-model lifecycle hooks; keys are"module.ClassName"paths, values map event names to lists of dotted callable paths. Supported events:before_validate,validate,before_insert,before_save,after_insert,on_change,on_update,on_delete,after_delete.OAuth2 Events
Field
Type
Default / Notes
OAUTH2_EVENTSdict[str, str]{}— lifecycle hooks for the OAuth2 flow; supported keys:on_success,on_fail,on_error,on_initialAI Integration
Field
Type
Default / Notes
ENABLE_AI_PROVIDERSboolFalseAI_PROVIDERSdict{}— provider-keyed configuration dictsOpenAPI / Swagger
Field
Type
Default / Notes
OPENAPI_TITLEstr"OpenViper API"OPENAPI_VERSIONstr"0.0.1"OPENAPI_DOCS_URLstr"/open-api/docs"OPENAPI_REDOC_URLstr"/open-api/redoc"OPENAPI_SCHEMA_URLstr"/open-api/openapi.json"OPENAPI_ENABLEDboolTrueOPENAPI_EXCLUDElist[str] | str[]— route prefixes to omit from the schema, or"__ALL__"to disable the OpenAPI router entirelyCountry Field
Field
Type
Default / Notes
COUNTRY_FIELDdict{"EXTRA_COUNTRIES": {}, "ENABLE_CACHE": True, "STRICT": True}— configuration forCountryField
- class openviper.conf.settings._LazySettings
The
settingssingleton. Attribute access triggers lazy loading of the settings module on first use.
Example Usage
See also
Every example project has its own settings.py — compare patterns:
examples/todoapp/settings.py — minimal single-app settings
examples/ai_moderation_platform/ — multi-app with
AI_PROVIDERS,TASKS,MODEL_EVENTSexamples/ecommerce_clone/ —
TASKS,AI_PROVIDERS,EMAILconfig
Defining Settings
# myproject/settings.py
import dataclasses
from openviper.conf import Settings
@dataclasses.dataclass(frozen=True)
class MySettings(Settings):
PROJECT_NAME: str = "MyBlog"
DATABASE_URL: str = "sqlite+aiosqlite:///db.sqlite3"
DEBUG: bool = False
SECRET_KEY: str = "" # set via OPENVIPER_SECRET_KEY env var
INSTALLED_APPS: tuple = (
"myproject.blog",
"myproject.users",
)
Then configure the environment:
export OPENVIPER_SETTINGS_MODULE=myproject.settings
export OPENVIPER_SECRET_KEY=your-secret-key-here
Accessing Settings
from openviper.conf import settings
print(settings.DEBUG) # False
print(settings.DATABASE_URL) # sqlite+aiosqlite:///db.sqlite3
Programmatic Configuration (Tests)
import dataclasses
from openviper.conf import Settings
from openviper.conf.settings import settings
settings.configure(Settings(
DATABASE_URL="sqlite+aiosqlite:///:memory:",
SECRET_KEY="test-only-secret",
DEBUG=True,
))
Environment Variable Overrides
Any settings field can be overridden at runtime by setting an environment
variable named OPENVIPER_<FIELD_NAME> (uppercase). For example:
export OPENVIPER_DEBUG=true
export OPENVIPER_LOG_LEVEL=DEBUG