We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Set up end-to-end tests


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `backend/settings/settings.py`
Content:
```
1 """
2 Django settings for settings project.
3 
4 Generated by 'django-admin startproject' using Django 3.2.4.
5 
6 For more information on this file, see
7 https://docs.djangoproject.com/en/3.2/topics/settings/
8 
9 For the full list of settings and their values, see
10 https://docs.djangoproject.com/en/3.2/ref/settings/
11 """
12 import os
13 import yaml
14 
15 from collections import OrderedDict
16 from pathlib import Path
17 
18 # Build paths inside the project like this: BASE_DIR / 'subdir'.
19 BASE_DIR = Path(__file__).resolve().parent.parent
20 
21 
22 server_settings = {}
23 SETTINGS_FILE = (
24     "SETTINGS_FILE" in os.environ
25     and os.environ["SETTINGS_FILE"]
26     or "/etc/django/settings-tournesol.yaml"
27 )
28 try:
29     with open(SETTINGS_FILE, "r") as f:
30         server_settings = yaml.full_load(f)
31 except FileNotFoundError:
32     print("No local settings.")
33     pass
34 
35 # Quick-start development settings - unsuitable for production
36 # See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
37 
38 # SECURITY WARNING: keep the secret key used in production secret!
39 SECRET_KEY = server_settings.get('SECRET_KEY', 'django-insecure-(=8(97oj$3)!#j!+^&bh_+5v5&1pfpzmaos#z80c!ia5@9#jz1')
40 
41 # SECURITY WARNING: don't run with debug turned on in production!
42 DEBUG = server_settings.get('DEBUG', False)
43 
44 ALLOWED_HOSTS = server_settings.get('ALLOWED_HOSTS', ['127.0.0.1', 'localhost'])
45 
46 STATIC_URL = "/static/"
47 MEDIA_URL = "/media/"
48 
49 # It is considered quite unsafe to use the /tmp directory, so we might as well use a dedicated root folder in HOME
50 base_folder = f"{os.environ.get('HOME')}/.tournesol"
51 STATIC_ROOT = server_settings.get('STATIC_ROOT', f"{base_folder}{STATIC_URL}")
52 MEDIA_ROOT = server_settings.get('MEDIA_ROOT', f"{base_folder}{MEDIA_URL}")
53 
54 MAIN_URL = server_settings.get('MAIN_URL', 'http://localhost:8000/')
55 
56 # Application definition
57 
58 INSTALLED_APPS = [
59     "django.contrib.admin",
60     "django.contrib.auth",
61     "django.contrib.contenttypes",
62     "django.contrib.sessions",
63     "django.contrib.messages",
64     "django.contrib.staticfiles",
65     "django_prometheus",
66     "core",
67     "tournesol",
68     "ml",
69     "oauth2_provider",
70     "corsheaders",
71     "rest_framework",
72     "drf_spectacular",
73     'rest_registration',
74 ]
75 
76 REST_REGISTRATION_MAIN_URL = server_settings.get('REST_REGISTRATION_MAIN_URL', 'http://127.0.0.1:3000/')
77 REST_REGISTRATION = {
78     'REGISTER_VERIFICATION_ENABLED': True,
79     'REGISTER_VERIFICATION_URL': REST_REGISTRATION_MAIN_URL + 'verify-user/',
80     'REGISTER_VERIFICATION_ONE_TIME_USE': True,
81     'RESET_PASSWORD_VERIFICATION_ENABLED': True,
82     'RESET_PASSWORD_VERIFICATION_URL': REST_REGISTRATION_MAIN_URL + 'reset-password/',
83     'RESET_PASSWORD_FAIL_WHEN_USER_NOT_FOUND': False, # to be set to True to prevent user enumeration
84     'RESET_PASSWORD_VERIFICATION_ONE_TIME_USE': True,
85     'REGISTER_EMAIL_SERIALIZER_CLASS': 'core.serializers.user.RegisterEmailSerializer',
86     'REGISTER_EMAIL_VERIFICATION_ENABLED': True,
87     'REGISTER_EMAIL_VERIFICATION_URL': REST_REGISTRATION_MAIN_URL + 'verify-email/',
88     'REGISTER_SERIALIZER_CLASS': 'core.serializers.user.RegisterUserSerializer',
89     'VERIFICATION_FROM_EMAIL': 'noreply@tournesol.app',
90 }
91 
92 EMAIL_BACKEND = server_settings.get('EMAIL_BACKEND', 'django.core.mail.backends.console.EmailBackend')
93 EMAIL_HOST = server_settings.get('EMAIL_HOST', '')
94 EMAIL_PORT = server_settings.get('EMAIL_PORT', '')
95 EMAIL_HOST_USER = server_settings.get('EMAIL_HOST_USER', '')
96 EMAIL_HOST_PASSWORD = server_settings.get('EMAIL_HOST_PASSWORD', '')
97 EMAIL_USE_TLS = server_settings.get('EMAIL_USE_TLS', '')
98 EMAIL_USE_SSL = server_settings.get('EMAIL_USE_SSL', '')
99 
100 
101 # Modèle utilisateur utilisé par Django (1.5+)
102 AUTH_USER_MODEL = "core.user"
103 
104 MIDDLEWARE = [
105     "django_prometheus.middleware.PrometheusBeforeMiddleware",
106     "django.middleware.security.SecurityMiddleware",
107     "django.contrib.sessions.middleware.SessionMiddleware",
108     "corsheaders.middleware.CorsMiddleware",
109     "django.middleware.common.CommonMiddleware",
110     "django.middleware.csrf.CsrfViewMiddleware",
111     "django.contrib.auth.middleware.AuthenticationMiddleware",
112     "django.contrib.messages.middleware.MessageMiddleware",
113     "django.middleware.clickjacking.XFrameOptionsMiddleware",
114     "django_prometheus.middleware.PrometheusAfterMiddleware",
115 ]
116 
117 ROOT_URLCONF = "settings.urls"
118 
119 TEMPLATES = [
120     {
121         "BACKEND": "django.template.backends.django.DjangoTemplates",
122         "DIRS": [BASE_DIR / "templates"],
123         "APP_DIRS": True,
124         "OPTIONS": {
125             "context_processors": [
126                 "django.template.context_processors.debug",
127                 "django.template.context_processors.request",
128                 "django.contrib.auth.context_processors.auth",
129                 "django.contrib.messages.context_processors.messages",
130             ],
131         },
132     },
133 ]
134 
135 WSGI_APPLICATION = "settings.wsgi.application"
136 
137 
138 # Database
139 # https://docs.djangoproject.com/en/3.2/ref/settings/#databases
140 
141 DATABASES = OrderedDict([
142     ['default', {
143         'ENGINE': 'django_prometheus.db.backends.postgresql',
144         'NAME': server_settings.get('DATABASE_NAME', 'tournesol'),
145         'USER': server_settings.get('DATABASE_USER', 'postgres'),
146         'PASSWORD': server_settings.get('DATABASE_PASSWORD', 'password'),
147         'HOST': server_settings.get("DATABASE_HOST", 'localhost'),
148         'PORT': server_settings.get("DATABASE_PORT", 5432),
149         'NUMBER': 42
150     }]
151 ])
152 
153 DRF_RECAPTCHA_PUBLIC_KEY = server_settings.get("DRF_RECAPTCHA_PUBLIC_KEY", 'dsfsdfdsfsdfsdfsdf')
154 DRF_RECAPTCHA_SECRET_KEY = server_settings.get("DRF_RECAPTCHA_SECRET_KEY", 'dsfsdfdsfsdf')
155 
156 
157 # Password validation
158 # https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
159 
160 AUTH_PASSWORD_VALIDATORS = [
161     {
162         "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
163     },
164     {
165         "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
166     },
167     {
168         "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
169     },
170     {
171         "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
172     },
173 ]
174 
175 
176 # Internationalization
177 # https://docs.djangoproject.com/en/3.2/topics/i18n/
178 
179 LANGUAGE_CODE = "en-us"
180 
181 TIME_ZONE = "UTC"
182 
183 USE_I18N = True
184 
185 USE_L10N = True
186 
187 USE_TZ = True
188 
189 
190 # Default primary key field type
191 # https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
192 
193 DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
194 
195 OAUTH2_PROVIDER = {
196     "OIDC_ENABLED": server_settings.get("OIDC_ENABLED", False),
197     "OIDC_RSA_PRIVATE_KEY": server_settings.get(
198         "OIDC_RSA_PRIVATE_KEY", "dsfsdfdsfsdfsdfsdf"
199     ),
200     "SCOPES": {
201         "openid": "OpenID Connect scope",
202         "read": "Read scope",
203         "write": "Write scope",
204         "groups": "Access to your groups",
205     },
206     "OAUTH2_VALIDATOR_CLASS": "core.oauth_validator.CustomOAuth2Validator",
207     "OIDC_ISS_ENDPOINT": server_settings.get("OIDC_ISS_ENDPOINT", ""),
208     "ACCESS_TOKEN_EXPIRE_SECONDS": server_settings.get(
209         "ACCESS_TOKEN_EXPIRE_SECONDS", 36000
210     ),  # 10h
211     "REFRESH_TOKEN_EXPIRE_SECONDS": server_settings.get(
212         "REFRESH_TOKEN_EXPIRE_SECONDS", 604800
213     ),  # 1w
214 }
215 LOGIN_URL = server_settings.get('LOGIN_URL', '')
216 
217 CORS_ALLOWED_ORIGINS = server_settings.get("CORS_ALLOWED_ORIGINS", [])
218 CORS_ALLOW_CREDENTIALS = server_settings.get("CORS_ALLOW_CREDENTIALS", False)
219 
220 REST_FRAMEWORK = {
221     # Use Django's standard `django.contrib.auth` permissions,
222     # or allow read-only access for unauthenticated users.
223     "DEFAULT_PERMISSION_CLASSES": [
224         "rest_framework.permissions.IsAuthenticated",
225     ],
226     "DEFAULT_FILTER_BACKENDS": ("django_filters.rest_framework.DjangoFilterBackend",),
227     "DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
228     "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination",
229     "PAGE_SIZE": 30,
230     # important to have no basic auth here
231     # as we are using Apache with basic auth
232     # https://stackoverflow.com/questions/40094823/django-rest-framework-invalid-username-password
233     "DEFAULT_AUTHENTICATION_CLASSES": (
234         "oauth2_provider.contrib.rest_framework.OAuth2Authentication",
235     ),
236     # custom exception handling
237     "DEFAULT_THROTTLE_CLASSES": [
238         "rest_framework.throttling.AnonRateThrottle",
239         "rest_framework.throttling.UserRateThrottle",
240     ],
241     "DEFAULT_THROTTLE_RATES": {"anon": "10000/hour", "user": "1000000/hour"},
242 }
243 
244 
245 # Maximal value for a rating (0-100)
246 # 0 means left video is best, 100 means right video is best
247 MAX_VALUE = 100.0
248 
249 CRITERIAS_DICT = OrderedDict(
250     [
251         ("largely_recommended", "Should be largely recommended"),
252         ("reliability", "Reliable and not misleading"),
253         ("importance", "Important and actionable"),
254         ("engaging", "Engaging and thought-provoking"),
255         ("pedagogy", "Clear and pedagogical"),
256         ("layman_friendly", "Layman-friendly"),
257         ("diversity_inclusion", "Diversity and Inclusion"),
258         ("backfire_risk", "Resilience to backfiring risks"),
259         ("better_habits", "Encourages better habits"),
260         ("entertaining_relaxing", "Entertaining and relaxing"),
261     ]
262 )
263 
264 CRITERIAS = list(CRITERIAS_DICT.keys())
265 
266 # maximal weight to assign to a rating for a particular feature, see #41
267 MAX_FEATURE_WEIGHT = 8
268 
269 SPECTACULAR_SETTINGS = {
270     "SWAGGER_UI_SETTINGS": {
271         "deepLinking": True,
272         "persistAuthorization": True,
273         "oauth2RedirectUrl": MAIN_URL + "docs/",
274     },
275     'SWAGGER_UI_OAUTH2_CONFIG': {
276         "clientId": server_settings.get("SWAGGER_UI_OAUTH2_CLIENT_ID",""),
277         "clientSecret": server_settings.get("SWAGGER_UI_OAUTH2_CLIENT_SECRET",""),
278         "appName": "Swagger UI",
279         "scopes": "read write groups",
280     },
281     'SECURITY': [{
282         'oauth2': ['read write groups'],
283     }],
284     'OAUTH2_FLOWS': ["password"],
285     'OAUTH2_AUTHORIZATION_URL': None,
286     'OAUTH2_TOKEN_URL': MAIN_URL + "o/token/",
287     'OAUTH2_REFRESH_URL': MAIN_URL + "o/token/",
288     'OAUTH2_SCOPES': "read write groups",
289 }
290 
291 YOUTUBE_API_KEY = os.environ.get("YOUTUBE_API_KEY", "")
292 
293 LOGGING = {
294     'version': 1,
295     'disable_existing_loggers': False,
296     'handlers': {
297         'console': {
298             'class': 'logging.StreamHandler',
299         },
300     },
301     'root': {
302         'handlers': ['console'],
303         'level': os.environ.get("DJANGO_LOG_LEVEL", "DEBUG"),
304     },
305 }
306
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/backend/settings/settings.py b/backend/settings/settings.py
--- a/backend/settings/settings.py
+++ b/backend/settings/settings.py
@@ -73,7 +73,7 @@
     'rest_registration',
 ]
 
-REST_REGISTRATION_MAIN_URL = server_settings.get('REST_REGISTRATION_MAIN_URL', 'http://127.0.0.1:3000/')
+REST_REGISTRATION_MAIN_URL = server_settings.get('REST_REGISTRATION_MAIN_URL', 'http://localhost:3000/')
 REST_REGISTRATION = {
     'REGISTER_VERIFICATION_ENABLED': True,
     'REGISTER_VERIFICATION_URL': REST_REGISTRATION_MAIN_URL + 'verify-user/',

{"golden_diff": "diff --git a/backend/settings/settings.py b/backend/settings/settings.py\n--- a/backend/settings/settings.py\n+++ b/backend/settings/settings.py\n@@ -73,7 +73,7 @@\n     'rest_registration',\n ]\n \n-REST_REGISTRATION_MAIN_URL = server_settings.get('REST_REGISTRATION_MAIN_URL', 'http://127.0.0.1:3000/')\n+REST_REGISTRATION_MAIN_URL = server_settings.get('REST_REGISTRATION_MAIN_URL', 'http://localhost:3000/')\n REST_REGISTRATION = {\n     'REGISTER_VERIFICATION_ENABLED': True,\n     'REGISTER_VERIFICATION_URL': REST_REGISTRATION_MAIN_URL + 'verify-user/',\n", "issue": "Set up end-to-end tests\n\n", "before_files": [{"content": "\"\"\"\nDjango settings for settings project.\n\nGenerated by 'django-admin startproject' using Django 3.2.4.\n\nFor more information on this file, see\nhttps://docs.djangoproject.com/en/3.2/topics/settings/\n\nFor the full list of settings and their values, see\nhttps://docs.djangoproject.com/en/3.2/ref/settings/\n\"\"\"\nimport os\nimport yaml\n\nfrom collections import OrderedDict\nfrom pathlib import Path\n\n# Build paths inside the project like this: BASE_DIR / 'subdir'.\nBASE_DIR = Path(__file__).resolve().parent.parent\n\n\nserver_settings = {}\nSETTINGS_FILE = (\n    \"SETTINGS_FILE\" in os.environ\n    and os.environ[\"SETTINGS_FILE\"]\n    or \"/etc/django/settings-tournesol.yaml\"\n)\ntry:\n    with open(SETTINGS_FILE, \"r\") as f:\n        server_settings = yaml.full_load(f)\nexcept FileNotFoundError:\n    print(\"No local settings.\")\n    pass\n\n# Quick-start development settings - unsuitable for production\n# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/\n\n# SECURITY WARNING: keep the secret key used in production secret!\nSECRET_KEY = server_settings.get('SECRET_KEY', 'django-insecure-(=8(97oj$3)!#j!+^&bh_+5v5&1pfpzmaos#z80c!ia5@9#jz1')\n\n# SECURITY WARNING: don't run with debug turned on in production!\nDEBUG = server_settings.get('DEBUG', False)\n\nALLOWED_HOSTS = server_settings.get('ALLOWED_HOSTS', ['127.0.0.1', 'localhost'])\n\nSTATIC_URL = \"/static/\"\nMEDIA_URL = \"/media/\"\n\n# It is considered quite unsafe to use the /tmp directory, so we might as well use a dedicated root folder in HOME\nbase_folder = f\"{os.environ.get('HOME')}/.tournesol\"\nSTATIC_ROOT = server_settings.get('STATIC_ROOT', f\"{base_folder}{STATIC_URL}\")\nMEDIA_ROOT = server_settings.get('MEDIA_ROOT', f\"{base_folder}{MEDIA_URL}\")\n\nMAIN_URL = server_settings.get('MAIN_URL', 'http://localhost:8000/')\n\n# Application definition\n\nINSTALLED_APPS = [\n    \"django.contrib.admin\",\n    \"django.contrib.auth\",\n    \"django.contrib.contenttypes\",\n    \"django.contrib.sessions\",\n    \"django.contrib.messages\",\n    \"django.contrib.staticfiles\",\n    \"django_prometheus\",\n    \"core\",\n    \"tournesol\",\n    \"ml\",\n    \"oauth2_provider\",\n    \"corsheaders\",\n    \"rest_framework\",\n    \"drf_spectacular\",\n    'rest_registration',\n]\n\nREST_REGISTRATION_MAIN_URL = server_settings.get('REST_REGISTRATION_MAIN_URL', 'http://127.0.0.1:3000/')\nREST_REGISTRATION = {\n    'REGISTER_VERIFICATION_ENABLED': True,\n    'REGISTER_VERIFICATION_URL': REST_REGISTRATION_MAIN_URL + 'verify-user/',\n    'REGISTER_VERIFICATION_ONE_TIME_USE': True,\n    'RESET_PASSWORD_VERIFICATION_ENABLED': True,\n    'RESET_PASSWORD_VERIFICATION_URL': REST_REGISTRATION_MAIN_URL + 'reset-password/',\n    'RESET_PASSWORD_FAIL_WHEN_USER_NOT_FOUND': False, # to be set to True to prevent user enumeration\n    'RESET_PASSWORD_VERIFICATION_ONE_TIME_USE': True,\n    'REGISTER_EMAIL_SERIALIZER_CLASS': 'core.serializers.user.RegisterEmailSerializer',\n    'REGISTER_EMAIL_VERIFICATION_ENABLED': True,\n    'REGISTER_EMAIL_VERIFICATION_URL': REST_REGISTRATION_MAIN_URL + 'verify-email/',\n    'REGISTER_SERIALIZER_CLASS': 'core.serializers.user.RegisterUserSerializer',\n    'VERIFICATION_FROM_EMAIL': 'noreply@tournesol.app',\n}\n\nEMAIL_BACKEND = server_settings.get('EMAIL_BACKEND', 'django.core.mail.backends.console.EmailBackend')\nEMAIL_HOST = server_settings.get('EMAIL_HOST', '')\nEMAIL_PORT = server_settings.get('EMAIL_PORT', '')\nEMAIL_HOST_USER = server_settings.get('EMAIL_HOST_USER', '')\nEMAIL_HOST_PASSWORD = server_settings.get('EMAIL_HOST_PASSWORD', '')\nEMAIL_USE_TLS = server_settings.get('EMAIL_USE_TLS', '')\nEMAIL_USE_SSL = server_settings.get('EMAIL_USE_SSL', '')\n\n\n# Mod\u00e8le utilisateur utilis\u00e9 par Django (1.5+)\nAUTH_USER_MODEL = \"core.user\"\n\nMIDDLEWARE = [\n    \"django_prometheus.middleware.PrometheusBeforeMiddleware\",\n    \"django.middleware.security.SecurityMiddleware\",\n    \"django.contrib.sessions.middleware.SessionMiddleware\",\n    \"corsheaders.middleware.CorsMiddleware\",\n    \"django.middleware.common.CommonMiddleware\",\n    \"django.middleware.csrf.CsrfViewMiddleware\",\n    \"django.contrib.auth.middleware.AuthenticationMiddleware\",\n    \"django.contrib.messages.middleware.MessageMiddleware\",\n    \"django.middleware.clickjacking.XFrameOptionsMiddleware\",\n    \"django_prometheus.middleware.PrometheusAfterMiddleware\",\n]\n\nROOT_URLCONF = \"settings.urls\"\n\nTEMPLATES = [\n    {\n        \"BACKEND\": \"django.template.backends.django.DjangoTemplates\",\n        \"DIRS\": [BASE_DIR / \"templates\"],\n        \"APP_DIRS\": True,\n        \"OPTIONS\": {\n            \"context_processors\": [\n                \"django.template.context_processors.debug\",\n                \"django.template.context_processors.request\",\n                \"django.contrib.auth.context_processors.auth\",\n                \"django.contrib.messages.context_processors.messages\",\n            ],\n        },\n    },\n]\n\nWSGI_APPLICATION = \"settings.wsgi.application\"\n\n\n# Database\n# https://docs.djangoproject.com/en/3.2/ref/settings/#databases\n\nDATABASES = OrderedDict([\n    ['default', {\n        'ENGINE': 'django_prometheus.db.backends.postgresql',\n        'NAME': server_settings.get('DATABASE_NAME', 'tournesol'),\n        'USER': server_settings.get('DATABASE_USER', 'postgres'),\n        'PASSWORD': server_settings.get('DATABASE_PASSWORD', 'password'),\n        'HOST': server_settings.get(\"DATABASE_HOST\", 'localhost'),\n        'PORT': server_settings.get(\"DATABASE_PORT\", 5432),\n        'NUMBER': 42\n    }]\n])\n\nDRF_RECAPTCHA_PUBLIC_KEY = server_settings.get(\"DRF_RECAPTCHA_PUBLIC_KEY\", 'dsfsdfdsfsdfsdfsdf')\nDRF_RECAPTCHA_SECRET_KEY = server_settings.get(\"DRF_RECAPTCHA_SECRET_KEY\", 'dsfsdfdsfsdf')\n\n\n# Password validation\n# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators\n\nAUTH_PASSWORD_VALIDATORS = [\n    {\n        \"NAME\": \"django.contrib.auth.password_validation.UserAttributeSimilarityValidator\",\n    },\n    {\n        \"NAME\": \"django.contrib.auth.password_validation.MinimumLengthValidator\",\n    },\n    {\n        \"NAME\": \"django.contrib.auth.password_validation.CommonPasswordValidator\",\n    },\n    {\n        \"NAME\": \"django.contrib.auth.password_validation.NumericPasswordValidator\",\n    },\n]\n\n\n# Internationalization\n# https://docs.djangoproject.com/en/3.2/topics/i18n/\n\nLANGUAGE_CODE = \"en-us\"\n\nTIME_ZONE = \"UTC\"\n\nUSE_I18N = True\n\nUSE_L10N = True\n\nUSE_TZ = True\n\n\n# Default primary key field type\n# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field\n\nDEFAULT_AUTO_FIELD = \"django.db.models.BigAutoField\"\n\nOAUTH2_PROVIDER = {\n    \"OIDC_ENABLED\": server_settings.get(\"OIDC_ENABLED\", False),\n    \"OIDC_RSA_PRIVATE_KEY\": server_settings.get(\n        \"OIDC_RSA_PRIVATE_KEY\", \"dsfsdfdsfsdfsdfsdf\"\n    ),\n    \"SCOPES\": {\n        \"openid\": \"OpenID Connect scope\",\n        \"read\": \"Read scope\",\n        \"write\": \"Write scope\",\n        \"groups\": \"Access to your groups\",\n    },\n    \"OAUTH2_VALIDATOR_CLASS\": \"core.oauth_validator.CustomOAuth2Validator\",\n    \"OIDC_ISS_ENDPOINT\": server_settings.get(\"OIDC_ISS_ENDPOINT\", \"\"),\n    \"ACCESS_TOKEN_EXPIRE_SECONDS\": server_settings.get(\n        \"ACCESS_TOKEN_EXPIRE_SECONDS\", 36000\n    ),  # 10h\n    \"REFRESH_TOKEN_EXPIRE_SECONDS\": server_settings.get(\n        \"REFRESH_TOKEN_EXPIRE_SECONDS\", 604800\n    ),  # 1w\n}\nLOGIN_URL = server_settings.get('LOGIN_URL', '')\n\nCORS_ALLOWED_ORIGINS = server_settings.get(\"CORS_ALLOWED_ORIGINS\", [])\nCORS_ALLOW_CREDENTIALS = server_settings.get(\"CORS_ALLOW_CREDENTIALS\", False)\n\nREST_FRAMEWORK = {\n    # Use Django's standard `django.contrib.auth` permissions,\n    # or allow read-only access for unauthenticated users.\n    \"DEFAULT_PERMISSION_CLASSES\": [\n        \"rest_framework.permissions.IsAuthenticated\",\n    ],\n    \"DEFAULT_FILTER_BACKENDS\": (\"django_filters.rest_framework.DjangoFilterBackend\",),\n    \"DEFAULT_SCHEMA_CLASS\": \"drf_spectacular.openapi.AutoSchema\",\n    \"DEFAULT_PAGINATION_CLASS\": \"rest_framework.pagination.LimitOffsetPagination\",\n    \"PAGE_SIZE\": 30,\n    # important to have no basic auth here\n    # as we are using Apache with basic auth\n    # https://stackoverflow.com/questions/40094823/django-rest-framework-invalid-username-password\n    \"DEFAULT_AUTHENTICATION_CLASSES\": (\n        \"oauth2_provider.contrib.rest_framework.OAuth2Authentication\",\n    ),\n    # custom exception handling\n    \"DEFAULT_THROTTLE_CLASSES\": [\n        \"rest_framework.throttling.AnonRateThrottle\",\n        \"rest_framework.throttling.UserRateThrottle\",\n    ],\n    \"DEFAULT_THROTTLE_RATES\": {\"anon\": \"10000/hour\", \"user\": \"1000000/hour\"},\n}\n\n\n# Maximal value for a rating (0-100)\n# 0 means left video is best, 100 means right video is best\nMAX_VALUE = 100.0\n\nCRITERIAS_DICT = OrderedDict(\n    [\n        (\"largely_recommended\", \"Should be largely recommended\"),\n        (\"reliability\", \"Reliable and not misleading\"),\n        (\"importance\", \"Important and actionable\"),\n        (\"engaging\", \"Engaging and thought-provoking\"),\n        (\"pedagogy\", \"Clear and pedagogical\"),\n        (\"layman_friendly\", \"Layman-friendly\"),\n        (\"diversity_inclusion\", \"Diversity and Inclusion\"),\n        (\"backfire_risk\", \"Resilience to backfiring risks\"),\n        (\"better_habits\", \"Encourages better habits\"),\n        (\"entertaining_relaxing\", \"Entertaining and relaxing\"),\n    ]\n)\n\nCRITERIAS = list(CRITERIAS_DICT.keys())\n\n# maximal weight to assign to a rating for a particular feature, see #41\nMAX_FEATURE_WEIGHT = 8\n\nSPECTACULAR_SETTINGS = {\n    \"SWAGGER_UI_SETTINGS\": {\n        \"deepLinking\": True,\n        \"persistAuthorization\": True,\n        \"oauth2RedirectUrl\": MAIN_URL + \"docs/\",\n    },\n    'SWAGGER_UI_OAUTH2_CONFIG': {\n        \"clientId\": server_settings.get(\"SWAGGER_UI_OAUTH2_CLIENT_ID\",\"\"),\n        \"clientSecret\": server_settings.get(\"SWAGGER_UI_OAUTH2_CLIENT_SECRET\",\"\"),\n        \"appName\": \"Swagger UI\",\n        \"scopes\": \"read write groups\",\n    },\n    'SECURITY': [{\n        'oauth2': ['read write groups'],\n    }],\n    'OAUTH2_FLOWS': [\"password\"],\n    'OAUTH2_AUTHORIZATION_URL': None,\n    'OAUTH2_TOKEN_URL': MAIN_URL + \"o/token/\",\n    'OAUTH2_REFRESH_URL': MAIN_URL + \"o/token/\",\n    'OAUTH2_SCOPES': \"read write groups\",\n}\n\nYOUTUBE_API_KEY = os.environ.get(\"YOUTUBE_API_KEY\", \"\")\n\nLOGGING = {\n    'version': 1,\n    'disable_existing_loggers': False,\n    'handlers': {\n        'console': {\n            'class': 'logging.StreamHandler',\n        },\n    },\n    'root': {\n        'handlers': ['console'],\n        'level': os.environ.get(\"DJANGO_LOG_LEVEL\", \"DEBUG\"),\n    },\n}\n", "path": "backend/settings/settings.py"}], "after_files": [{"content": "\"\"\"\nDjango settings for settings project.\n\nGenerated by 'django-admin startproject' using Django 3.2.4.\n\nFor more information on this file, see\nhttps://docs.djangoproject.com/en/3.2/topics/settings/\n\nFor the full list of settings and their values, see\nhttps://docs.djangoproject.com/en/3.2/ref/settings/\n\"\"\"\nimport os\nimport yaml\n\nfrom collections import OrderedDict\nfrom pathlib import Path\n\n# Build paths inside the project like this: BASE_DIR / 'subdir'.\nBASE_DIR = Path(__file__).resolve().parent.parent\n\n\nserver_settings = {}\nSETTINGS_FILE = (\n    \"SETTINGS_FILE\" in os.environ\n    and os.environ[\"SETTINGS_FILE\"]\n    or \"/etc/django/settings-tournesol.yaml\"\n)\ntry:\n    with open(SETTINGS_FILE, \"r\") as f:\n        server_settings = yaml.full_load(f)\nexcept FileNotFoundError:\n    print(\"No local settings.\")\n    pass\n\n# Quick-start development settings - unsuitable for production\n# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/\n\n# SECURITY WARNING: keep the secret key used in production secret!\nSECRET_KEY = server_settings.get('SECRET_KEY', 'django-insecure-(=8(97oj$3)!#j!+^&bh_+5v5&1pfpzmaos#z80c!ia5@9#jz1')\n\n# SECURITY WARNING: don't run with debug turned on in production!\nDEBUG = server_settings.get('DEBUG', False)\n\nALLOWED_HOSTS = server_settings.get('ALLOWED_HOSTS', ['127.0.0.1', 'localhost'])\n\nSTATIC_URL = \"/static/\"\nMEDIA_URL = \"/media/\"\n\n# It is considered quite unsafe to use the /tmp directory, so we might as well use a dedicated root folder in HOME\nbase_folder = f\"{os.environ.get('HOME')}/.tournesol\"\nSTATIC_ROOT = server_settings.get('STATIC_ROOT', f\"{base_folder}{STATIC_URL}\")\nMEDIA_ROOT = server_settings.get('MEDIA_ROOT', f\"{base_folder}{MEDIA_URL}\")\n\nMAIN_URL = server_settings.get('MAIN_URL', 'http://localhost:8000/')\n\n# Application definition\n\nINSTALLED_APPS = [\n    \"django.contrib.admin\",\n    \"django.contrib.auth\",\n    \"django.contrib.contenttypes\",\n    \"django.contrib.sessions\",\n    \"django.contrib.messages\",\n    \"django.contrib.staticfiles\",\n    \"django_prometheus\",\n    \"core\",\n    \"tournesol\",\n    \"ml\",\n    \"oauth2_provider\",\n    \"corsheaders\",\n    \"rest_framework\",\n    \"drf_spectacular\",\n    'rest_registration',\n]\n\nREST_REGISTRATION_MAIN_URL = server_settings.get('REST_REGISTRATION_MAIN_URL', 'http://localhost:3000/')\nREST_REGISTRATION = {\n    'REGISTER_VERIFICATION_ENABLED': True,\n    'REGISTER_VERIFICATION_URL': REST_REGISTRATION_MAIN_URL + 'verify-user/',\n    'REGISTER_VERIFICATION_ONE_TIME_USE': True,\n    'RESET_PASSWORD_VERIFICATION_ENABLED': True,\n    'RESET_PASSWORD_VERIFICATION_URL': REST_REGISTRATION_MAIN_URL + 'reset-password/',\n    'RESET_PASSWORD_FAIL_WHEN_USER_NOT_FOUND': False, # to be set to True to prevent user enumeration\n    'RESET_PASSWORD_VERIFICATION_ONE_TIME_USE': True,\n    'REGISTER_EMAIL_SERIALIZER_CLASS': 'core.serializers.user.RegisterEmailSerializer',\n    'REGISTER_EMAIL_VERIFICATION_ENABLED': True,\n    'REGISTER_EMAIL_VERIFICATION_URL': REST_REGISTRATION_MAIN_URL + 'verify-email/',\n    'REGISTER_SERIALIZER_CLASS': 'core.serializers.user.RegisterUserSerializer',\n    'VERIFICATION_FROM_EMAIL': 'noreply@tournesol.app',\n}\n\nEMAIL_BACKEND = server_settings.get('EMAIL_BACKEND', 'django.core.mail.backends.console.EmailBackend')\nEMAIL_HOST = server_settings.get('EMAIL_HOST', '')\nEMAIL_PORT = server_settings.get('EMAIL_PORT', '')\nEMAIL_HOST_USER = server_settings.get('EMAIL_HOST_USER', '')\nEMAIL_HOST_PASSWORD = server_settings.get('EMAIL_HOST_PASSWORD', '')\nEMAIL_USE_TLS = server_settings.get('EMAIL_USE_TLS', '')\nEMAIL_USE_SSL = server_settings.get('EMAIL_USE_SSL', '')\n\n\n# Mod\u00e8le utilisateur utilis\u00e9 par Django (1.5+)\nAUTH_USER_MODEL = \"core.user\"\n\nMIDDLEWARE = [\n    \"django_prometheus.middleware.PrometheusBeforeMiddleware\",\n    \"django.middleware.security.SecurityMiddleware\",\n    \"django.contrib.sessions.middleware.SessionMiddleware\",\n    \"corsheaders.middleware.CorsMiddleware\",\n    \"django.middleware.common.CommonMiddleware\",\n    \"django.middleware.csrf.CsrfViewMiddleware\",\n    \"django.contrib.auth.middleware.AuthenticationMiddleware\",\n    \"django.contrib.messages.middleware.MessageMiddleware\",\n    \"django.middleware.clickjacking.XFrameOptionsMiddleware\",\n    \"django_prometheus.middleware.PrometheusAfterMiddleware\",\n]\n\nROOT_URLCONF = \"settings.urls\"\n\nTEMPLATES = [\n    {\n        \"BACKEND\": \"django.template.backends.django.DjangoTemplates\",\n        \"DIRS\": [BASE_DIR / \"templates\"],\n        \"APP_DIRS\": True,\n        \"OPTIONS\": {\n            \"context_processors\": [\n                \"django.template.context_processors.debug\",\n                \"django.template.context_processors.request\",\n                \"django.contrib.auth.context_processors.auth\",\n                \"django.contrib.messages.context_processors.messages\",\n            ],\n        },\n    },\n]\n\nWSGI_APPLICATION = \"settings.wsgi.application\"\n\n\n# Database\n# https://docs.djangoproject.com/en/3.2/ref/settings/#databases\n\nDATABASES = OrderedDict([\n    ['default', {\n        'ENGINE': 'django_prometheus.db.backends.postgresql',\n        'NAME': server_settings.get('DATABASE_NAME', 'tournesol'),\n        'USER': server_settings.get('DATABASE_USER', 'postgres'),\n        'PASSWORD': server_settings.get('DATABASE_PASSWORD', 'password'),\n        'HOST': server_settings.get(\"DATABASE_HOST\", 'localhost'),\n        'PORT': server_settings.get(\"DATABASE_PORT\", 5432),\n        'NUMBER': 42\n    }]\n])\n\nDRF_RECAPTCHA_PUBLIC_KEY = server_settings.get(\"DRF_RECAPTCHA_PUBLIC_KEY\", 'dsfsdfdsfsdfsdfsdf')\nDRF_RECAPTCHA_SECRET_KEY = server_settings.get(\"DRF_RECAPTCHA_SECRET_KEY\", 'dsfsdfdsfsdf')\n\n\n# Password validation\n# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators\n\nAUTH_PASSWORD_VALIDATORS = [\n    {\n        \"NAME\": \"django.contrib.auth.password_validation.UserAttributeSimilarityValidator\",\n    },\n    {\n        \"NAME\": \"django.contrib.auth.password_validation.MinimumLengthValidator\",\n    },\n    {\n        \"NAME\": \"django.contrib.auth.password_validation.CommonPasswordValidator\",\n    },\n    {\n        \"NAME\": \"django.contrib.auth.password_validation.NumericPasswordValidator\",\n    },\n]\n\n\n# Internationalization\n# https://docs.djangoproject.com/en/3.2/topics/i18n/\n\nLANGUAGE_CODE = \"en-us\"\n\nTIME_ZONE = \"UTC\"\n\nUSE_I18N = True\n\nUSE_L10N = True\n\nUSE_TZ = True\n\n\n# Default primary key field type\n# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field\n\nDEFAULT_AUTO_FIELD = \"django.db.models.BigAutoField\"\n\nOAUTH2_PROVIDER = {\n    \"OIDC_ENABLED\": server_settings.get(\"OIDC_ENABLED\", False),\n    \"OIDC_RSA_PRIVATE_KEY\": server_settings.get(\n        \"OIDC_RSA_PRIVATE_KEY\", \"dsfsdfdsfsdfsdfsdf\"\n    ),\n    \"SCOPES\": {\n        \"openid\": \"OpenID Connect scope\",\n        \"read\": \"Read scope\",\n        \"write\": \"Write scope\",\n        \"groups\": \"Access to your groups\",\n    },\n    \"OAUTH2_VALIDATOR_CLASS\": \"core.oauth_validator.CustomOAuth2Validator\",\n    \"OIDC_ISS_ENDPOINT\": server_settings.get(\"OIDC_ISS_ENDPOINT\", \"\"),\n    \"ACCESS_TOKEN_EXPIRE_SECONDS\": server_settings.get(\n        \"ACCESS_TOKEN_EXPIRE_SECONDS\", 36000\n    ),  # 10h\n    \"REFRESH_TOKEN_EXPIRE_SECONDS\": server_settings.get(\n        \"REFRESH_TOKEN_EXPIRE_SECONDS\", 604800\n    ),  # 1w\n}\nLOGIN_URL = server_settings.get('LOGIN_URL', '')\n\nCORS_ALLOWED_ORIGINS = server_settings.get(\"CORS_ALLOWED_ORIGINS\", [])\nCORS_ALLOW_CREDENTIALS = server_settings.get(\"CORS_ALLOW_CREDENTIALS\", False)\n\nREST_FRAMEWORK = {\n    # Use Django's standard `django.contrib.auth` permissions,\n    # or allow read-only access for unauthenticated users.\n    \"DEFAULT_PERMISSION_CLASSES\": [\n        \"rest_framework.permissions.IsAuthenticated\",\n    ],\n    \"DEFAULT_FILTER_BACKENDS\": (\"django_filters.rest_framework.DjangoFilterBackend\",),\n    \"DEFAULT_SCHEMA_CLASS\": \"drf_spectacular.openapi.AutoSchema\",\n    \"DEFAULT_PAGINATION_CLASS\": \"rest_framework.pagination.LimitOffsetPagination\",\n    \"PAGE_SIZE\": 30,\n    # important to have no basic auth here\n    # as we are using Apache with basic auth\n    # https://stackoverflow.com/questions/40094823/django-rest-framework-invalid-username-password\n    \"DEFAULT_AUTHENTICATION_CLASSES\": (\n        \"oauth2_provider.contrib.rest_framework.OAuth2Authentication\",\n    ),\n    # custom exception handling\n    \"DEFAULT_THROTTLE_CLASSES\": [\n        \"rest_framework.throttling.AnonRateThrottle\",\n        \"rest_framework.throttling.UserRateThrottle\",\n    ],\n    \"DEFAULT_THROTTLE_RATES\": {\"anon\": \"10000/hour\", \"user\": \"1000000/hour\"},\n}\n\n\n# Maximal value for a rating (0-100)\n# 0 means left video is best, 100 means right video is best\nMAX_VALUE = 100.0\n\nCRITERIAS_DICT = OrderedDict(\n    [\n        (\"largely_recommended\", \"Should be largely recommended\"),\n        (\"reliability\", \"Reliable and not misleading\"),\n        (\"importance\", \"Important and actionable\"),\n        (\"engaging\", \"Engaging and thought-provoking\"),\n        (\"pedagogy\", \"Clear and pedagogical\"),\n        (\"layman_friendly\", \"Layman-friendly\"),\n        (\"diversity_inclusion\", \"Diversity and Inclusion\"),\n        (\"backfire_risk\", \"Resilience to backfiring risks\"),\n        (\"better_habits\", \"Encourages better habits\"),\n        (\"entertaining_relaxing\", \"Entertaining and relaxing\"),\n    ]\n)\n\nCRITERIAS = list(CRITERIAS_DICT.keys())\n\n# maximal weight to assign to a rating for a particular feature, see #41\nMAX_FEATURE_WEIGHT = 8\n\nSPECTACULAR_SETTINGS = {\n    \"SWAGGER_UI_SETTINGS\": {\n        \"deepLinking\": True,\n        \"persistAuthorization\": True,\n        \"oauth2RedirectUrl\": MAIN_URL + \"docs/\",\n    },\n    'SWAGGER_UI_OAUTH2_CONFIG': {\n        \"clientId\": server_settings.get(\"SWAGGER_UI_OAUTH2_CLIENT_ID\",\"\"),\n        \"clientSecret\": server_settings.get(\"SWAGGER_UI_OAUTH2_CLIENT_SECRET\",\"\"),\n        \"appName\": \"Swagger UI\",\n        \"scopes\": \"read write groups\",\n    },\n    'SECURITY': [{\n        'oauth2': ['read write groups'],\n    }],\n    'OAUTH2_FLOWS': [\"password\"],\n    'OAUTH2_AUTHORIZATION_URL': None,\n    'OAUTH2_TOKEN_URL': MAIN_URL + \"o/token/\",\n    'OAUTH2_REFRESH_URL': MAIN_URL + \"o/token/\",\n    'OAUTH2_SCOPES': \"read write groups\",\n}\n\nYOUTUBE_API_KEY = os.environ.get(\"YOUTUBE_API_KEY\", \"\")\n\nLOGGING = {\n    'version': 1,\n    'disable_existing_loggers': False,\n    'handlers': {\n        'console': {\n            'class': 'logging.StreamHandler',\n        },\n    },\n    'root': {\n        'handlers': ['console'],\n        'level': os.environ.get(\"DJANGO_LOG_LEVEL\", \"DEBUG\"),\n    },\n}\n", "path": "backend/settings/settings.py"}]}