davidtran999 commited on
Commit
0ade73a
·
verified ·
1 Parent(s): 3adff5e

Upload backend/hue_portal/settings.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. backend/hue_portal/settings.py +210 -0
backend/hue_portal/settings.py ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import time
3
+ from pathlib import Path
4
+ import environ
5
+
6
+ BASE_DIR = Path(__file__).resolve().parent.parent
7
+ env = environ.Env()
8
+ environ.Env.read_env(os.path.join(BASE_DIR, "..", ".env"))
9
+
10
+ SECRET_KEY = env("DJANGO_SECRET_KEY", default="change-me")
11
+ DEBUG = env.bool("DJANGO_DEBUG", default=False)
12
+ ALLOWED_HOSTS = env.list("DJANGO_ALLOWED_HOSTS", default=["*"])
13
+
14
+ INSTALLED_APPS = [
15
+ "django.contrib.admin",
16
+ "django.contrib.auth",
17
+ "django.contrib.contenttypes",
18
+ "django.contrib.sessions",
19
+ "django.contrib.messages",
20
+ "django.contrib.staticfiles",
21
+ "django.contrib.postgres",
22
+ "corsheaders",
23
+ "rest_framework",
24
+ "hue_portal.core",
25
+ "hue_portal.chatbot",
26
+ ]
27
+
28
+ MIDDLEWARE = [
29
+ "django.middleware.security.SecurityMiddleware",
30
+ "whitenoise.middleware.WhiteNoiseMiddleware",
31
+ "django.middleware.gzip.GZipMiddleware",
32
+ "corsheaders.middleware.CorsMiddleware",
33
+ "django.middleware.common.CommonMiddleware",
34
+ "django.middleware.csrf.CsrfViewMiddleware",
35
+ "django.contrib.sessions.middleware.SessionMiddleware",
36
+ "django.contrib.auth.middleware.AuthenticationMiddleware",
37
+ "django.contrib.messages.middleware.MessageMiddleware",
38
+ "django.middleware.clickjacking.XFrameOptionsMiddleware",
39
+ "hue_portal.core.middleware.SecurityHeadersMiddleware",
40
+ "hue_portal.core.middleware.AuditLogMiddleware",
41
+ ]
42
+
43
+ ROOT_URLCONF = "hue_portal.hue_portal.urls"
44
+
45
+ TEMPLATES = [
46
+ {
47
+ "BACKEND": "django.template.backends.django.DjangoTemplates",
48
+ "DIRS": [],
49
+ "APP_DIRS": True,
50
+ "OPTIONS": {
51
+ "context_processors": [
52
+ "django.template.context_processors.debug",
53
+ "django.template.context_processors.request",
54
+ "django.contrib.auth.context_processors.auth",
55
+ "django.contrib.messages.context_processors.messages",
56
+ ],
57
+ },
58
+ },
59
+ ]
60
+
61
+ WSGI_APPLICATION = "hue_portal.hue_portal.wsgi.application"
62
+
63
+ def _mask(value: str) -> str:
64
+ if not value:
65
+ return ""
66
+ return value[:4] + "***"
67
+
68
+ database_url = env("DATABASE_URL", default=None)
69
+
70
+ if database_url:
71
+ DATABASES = {"default": env.db("DATABASE_URL")}
72
+ masked = database_url.replace(env("POSTGRES_PASSWORD", default=""), "***")
73
+ print(f"[DB] Using DATABASE_URL: {masked}", flush=True)
74
+ else:
75
+ print("[DB] DATABASE_URL not provided – thử kết nối qua POSTGRES_* / tunnel.", flush=True)
76
+ try:
77
+ import psycopg2
78
+
79
+ host = env("POSTGRES_HOST", default="localhost")
80
+ port = env("POSTGRES_PORT", default="5543")
81
+ user = env("POSTGRES_USER", default="hue")
82
+ password = env("POSTGRES_PASSWORD", default="huepass")
83
+ database = env("POSTGRES_DB", default="hue_portal")
84
+
85
+ last_error = None
86
+ for attempt in range(1, 4):
87
+ try:
88
+ test_conn = psycopg2.connect(
89
+ host=host,
90
+ port=port,
91
+ user=user,
92
+ password=password,
93
+ database=database,
94
+ connect_timeout=3,
95
+ )
96
+ test_conn.close()
97
+ last_error = None
98
+ break
99
+ except psycopg2.OperationalError as exc:
100
+ last_error = exc
101
+ print(
102
+ f"[DB] Attempt {attempt}/3 failed to reach PostgreSQL ({exc}).",
103
+ flush=True,
104
+ )
105
+ time.sleep(1)
106
+
107
+ if last_error:
108
+ raise last_error
109
+
110
+ DATABASES = {
111
+ "default": {
112
+ "ENGINE": "django.db.backends.postgresql",
113
+ "NAME": database,
114
+ "USER": user,
115
+ "PASSWORD": password,
116
+ "HOST": host,
117
+ "PORT": port,
118
+ }
119
+ }
120
+ print(
121
+ f"[DB] Connected to PostgreSQL at {host}:{port} as {_mask(user)}",
122
+ flush=True,
123
+ )
124
+ except Exception as db_error:
125
+ print(
126
+ f"[DB] ⚠️ Falling back to SQLite because PostgreSQL is unavailable ({db_error})",
127
+ flush=True,
128
+ )
129
+ DATABASES = {
130
+ "default": {
131
+ "ENGINE": "django.db.backends.sqlite3",
132
+ "NAME": BASE_DIR / "db.sqlite3",
133
+ }
134
+ }
135
+
136
+ # Cache configuration: opt-in Redis, otherwise safe local cache
137
+ USE_REDIS_CACHE = env.bool("ENABLE_REDIS_CACHE", default=False)
138
+ _redis_configured = False
139
+
140
+ if USE_REDIS_CACHE:
141
+ try:
142
+ import redis
143
+ from urllib.parse import urlparse
144
+
145
+ redis_url = env("REDIS_URL", default="redis://localhost:6380/0")
146
+ parsed = urlparse(redis_url)
147
+ test_client = redis.Redis(
148
+ host=parsed.hostname or "localhost",
149
+ port=parsed.port or 6380,
150
+ username=parsed.username,
151
+ password=parsed.password,
152
+ db=int(parsed.path.lstrip("/") or 0),
153
+ socket_connect_timeout=1,
154
+ )
155
+ test_client.ping()
156
+ test_client.close()
157
+
158
+ CACHES = {
159
+ "default": {
160
+ "BACKEND": "django.core.cache.backends.redis.RedisCache",
161
+ "LOCATION": redis_url,
162
+ }
163
+ }
164
+ _redis_configured = True
165
+ print(f"[CACHE] ✅ Using Redis cache at {redis_url}", flush=True)
166
+ except Exception as redis_error:
167
+ print(f"[CACHE] ⚠️ Redis unavailable ({redis_error}), falling back to local cache.", flush=True)
168
+
169
+ if not _redis_configured:
170
+ # LocMemCache keeps throttling functional without external services
171
+ CACHES = {
172
+ "default": {
173
+ "BACKEND": "django.core.cache.backends.locmem.LocMemCache",
174
+ "LOCATION": "hue-portal-default-cache",
175
+ }
176
+ }
177
+ # Reduce throttling aggressiveness failures by ensuring predictable cache
178
+ print("[CACHE] ℹ️ Using in-memory cache (LocMemCache).", flush=True)
179
+
180
+ REST_FRAMEWORK = {
181
+ "DEFAULT_RENDERER_CLASSES": ["rest_framework.renderers.JSONRenderer"],
182
+ "DEFAULT_PARSER_CLASSES": ["rest_framework.parsers.JSONParser"],
183
+ "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.PageNumberPagination",
184
+ "PAGE_SIZE": 20,
185
+ "DEFAULT_THROTTLE_CLASSES": [
186
+ "rest_framework.throttling.AnonRateThrottle",
187
+ ],
188
+ "DEFAULT_THROTTLE_RATES": {
189
+ "anon": "60/minute",
190
+ },
191
+ }
192
+
193
+ STATIC_URL = "/static/"
194
+ STATIC_ROOT = BASE_DIR / "static"
195
+
196
+ CORS_ALLOW_ALL_ORIGINS = env.bool("CORS_ALLOW_ALL_ORIGINS", default=True) # Allow all in dev
197
+ CORS_ALLOWED_ORIGINS = env.list("CORS_ALLOWED_ORIGINS", default=["http://localhost:3000", "http://127.0.0.1:3000", "http://localhost:5173", "http://127.0.0.1:5173"])
198
+ CORS_ALLOW_CREDENTIALS = True
199
+ CORS_ALLOW_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"]
200
+ CORS_ALLOW_HEADERS = ["*"]
201
+
202
+ SECURE_HSTS_SECONDS = 31536000
203
+ SECURE_SSL_REDIRECT = False
204
+ SESSION_COOKIE_SECURE = True
205
+ CSRF_COOKIE_SECURE = True
206
+ SECURE_CONTENT_TYPE_NOSNIFF = True
207
+ SECURE_BROWSER_XSS_FILTER = True
208
+
209
+ DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
210
+