Coverage for cookie / settings.py: 92%

39 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-01-11 00:40 +0000

1""" 

2Django settings for cookie project. 

3Single settings file for simplicity. 

4""" 

5 

6import os 

7from pathlib import Path 

8 

9BASE_DIR = Path(__file__).resolve().parent.parent 

10 

11# =========================================== 

12# Environment-based Configuration 

13# =========================================== 

14 

15DEBUG = os.environ.get('DEBUG', 'True').lower() == 'true' 

16 

17def get_secret_key(): 

18 """Get secret key from environment or generate one.""" 

19 env_key = os.environ.get('SECRET_KEY') 

20 if env_key: 

21 return env_key 

22 if DEBUG: 

23 return 'django-insecure-dev-key-change-in-production' 

24 from django.core.management.utils import get_random_secret_key 

25 return get_random_secret_key() 

26 

27SECRET_KEY = get_secret_key() 

28 

29ALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS', '*').split(',') 

30 

31# CSRF trusted origins (for reverse proxies) 

32csrf_origins = os.environ.get('CSRF_TRUSTED_ORIGINS', '') 

33CSRF_TRUSTED_ORIGINS = [o.strip() for o in csrf_origins.split(',') if o.strip()] 

34 

35INSTALLED_APPS = [ 

36 'django.contrib.contenttypes', 

37 'django.contrib.sessions', 

38 'django.contrib.staticfiles', 

39 'apps.core', 

40 'apps.profiles', 

41 'apps.recipes', 

42 'apps.ai', 

43 'apps.legacy', 

44] 

45 

46MIDDLEWARE = [ 

47 'django.middleware.security.SecurityMiddleware', 

48 'whitenoise.middleware.WhiteNoiseMiddleware', 

49 'django.contrib.sessions.middleware.SessionMiddleware', 

50 'django.middleware.common.CommonMiddleware', 

51 'apps.core.middleware.DeviceDetectionMiddleware', 

52] 

53 

54ROOT_URLCONF = 'cookie.urls' 

55 

56TEMPLATES = [ 

57 { 

58 'BACKEND': 'django.template.backends.django.DjangoTemplates', 

59 'DIRS': [], 

60 'APP_DIRS': True, 

61 'OPTIONS': { 

62 'context_processors': [ 

63 'django.template.context_processors.debug', 

64 'django.template.context_processors.request', 

65 ], 

66 }, 

67 }, 

68] 

69 

70WSGI_APPLICATION = 'cookie.wsgi.application' 

71 

72# Support custom database path for Docker volumes 

73DATABASE_PATH = os.environ.get('DATABASE_PATH', str(BASE_DIR / 'db.sqlite3')) 

74 

75DATABASES = { 

76 'default': { 

77 'ENGINE': 'django.db.backends.sqlite3', 

78 'NAME': DATABASE_PATH, 

79 'OPTIONS': { 

80 # Increase lock wait timeout from default 5s to 20s 

81 'timeout': 20, 

82 # Acquire write lock at transaction START (not mid-transaction) 

83 # This prevents "database is locked" errors during concurrent writes 

84 # by allowing failed lock acquisitions to be retried 

85 'transaction_mode': 'IMMEDIATE', 

86 # PRAGMA settings applied on each new connection: 

87 # - journal_mode=WAL: Allow concurrent reads during writes 

88 # - synchronous=NORMAL: Safe for WAL mode, better performance 

89 # - busy_timeout=5000: Wait up to 5s for locks at SQLite level 

90 'init_command': ( 

91 'PRAGMA journal_mode=WAL;' 

92 'PRAGMA synchronous=NORMAL;' 

93 'PRAGMA busy_timeout=5000;' 

94 ), 

95 }, 

96 } 

97} 

98 

99LANGUAGE_CODE = 'en-us' 

100TIME_ZONE = 'UTC' 

101USE_I18N = True 

102USE_TZ = True 

103 

104STATIC_URL = 'static/' 

105STATIC_ROOT = BASE_DIR / 'staticfiles' 

106 

107# Include built frontend assets in static files (only if directory exists) 

108_frontend_dist = BASE_DIR / 'frontend' / 'dist' 

109STATICFILES_DIRS = [_frontend_dist] if _frontend_dist.exists() else [] 

110 

111# WhiteNoise configuration for efficient static file serving 

112STORAGES = { 

113 "default": { 

114 "BACKEND": "django.core.files.storage.FileSystemStorage", 

115 }, 

116 "staticfiles": { 

117 "BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage", 

118 }, 

119} 

120 

121MEDIA_URL = '/media/' 

122data_dir = os.environ.get('DATA_DIR', str(BASE_DIR)) 

123MEDIA_ROOT = Path(data_dir) / 'data' / 'media' if not DEBUG else BASE_DIR / 'media' 

124 

125DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' 

126 

127# Session settings 

128SESSION_ENGINE = 'django.contrib.sessions.backends.db' 

129SESSION_COOKIE_AGE = 43200 # 12 hours 

130 

131# Logging configuration 

132LOGGING = { 

133 'version': 1, 

134 'disable_existing_loggers': False, 

135 'formatters': { 

136 'verbose': { 

137 'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}', 

138 'style': '{', 

139 }, 

140 'simple': { 

141 'format': '{levelname} {message}', 

142 'style': '{', 

143 }, 

144 }, 

145 'handlers': { 

146 'console': { 

147 'class': 'logging.StreamHandler', 

148 'formatter': 'verbose', 

149 }, 

150 }, 

151 'loggers': { 

152 'apps.recipes': { 

153 'handlers': ['console'], 

154 'level': 'INFO', 

155 'propagate': False, 

156 }, 

157 'apps.recipes.services': { 

158 'handlers': ['console'], 

159 'level': 'INFO', 

160 'propagate': False, 

161 }, 

162 'apps.ai': { 

163 'handlers': ['console'], 

164 'level': 'INFO', 

165 'propagate': False, 

166 }, 

167 }, 

168 'root': { 

169 'handlers': ['console'], 

170 'level': 'WARNING', 

171 }, 

172} 

← Back to Dashboard