We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[Bug] API not adding CORS headers to responses
## Description
<!-- Concisely describe the bug. -->
When trying to use the API locally with the Frontend project I got the following message in the browser's console:

> Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8000/v1/images?q=birds. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).

This is from Firefox but a very similar one will show in Chrome too, preventing to get any useful response.

## Reproduction
<!-- Provide detailed steps to reproduce the bug. -->
1. Run this project normally (instructions in README)
2. Simultaneously, run the [Frontend][ov-fe] project using the local API
```bash
API_URL=http://localhost:8000/v1/ npm run dev
```
3. Open the browser and try to search anything
4. See error.


## Expectation
<!-- Concisely describe what you expected to happen. -->
It should be possible to access the API from any domain, as [_is already intended_][ov-api-config], but a slightly misconfiguration is impeding.


## Screenshots
<!-- Add screenshots to show the problem; or delete the section entirely. -->

<img width="814" alt="Screen Shot 2021-08-25 at 7 17 32 PM" src="https://user-images.githubusercontent.com/9145885/130876641-1e2f13ac-2717-4ce1-a555-46aa94133967.png">


[ov-fe]: https://github.com/WordPress/openverse-frontend
[ov-api-config]: https://github.com/WordPress/openverse-api/blob/main/openverse-api/catalog/settings.py#L286:L287

## Resolution
<!-- Replace the [ ] with [x] to check the box. -->
- [x] 🙋 I would be interested in resolving this bug.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `openverse-api/catalog/settings.py`
Content:
```
1 """
2 Django settings for catalog project.
3 
4 Generated by 'django-admin startproject' using Django 2.0.5.
5 
6 For more information on this file, see
7 https://docs.djangoproject.com/en/2.0/topics/settings/
8 
9 For the full list of settings and their values, see
10 https://docs.djangoproject.com/en/2.0/ref/settings/
11 """
12 import os
13 from pathlib import Path
14 from socket import gethostname, gethostbyname
15 true_strings = ['true', 'True', 't', '1']
16 
17 # Build paths inside the project like this: BASE_DIR.join('dir', 'subdir'...)
18 BASE_DIR = Path(__file__).resolve().parent.parent
19 
20 # Where to collect static files in production/development deployments
21 STATIC_ROOT = "/var/api_static_content/static"
22 
23 # Logo uploads
24 MEDIA_ROOT = '/var/api_media/'
25 MEDIA_URL = '/media/'
26 
27 # Quick-start development settings - unsuitable for production
28 # See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/
29 
30 # SECURITY WARNING: keep the secret key used in production secret!
31 SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY')
32 
33 # SECURITY WARNING: don't run with debug turned on in production!
34 DEBUG = os.environ.get('DJANGO_DEBUG_ENABLED', default=False) in true_strings
35 
36 ALLOWED_HOSTS = ['localhost', '127.0.0.1', os.environ.get('LOAD_BALANCER_URL'),
37                  'api-dev.openverse.engineering',
38                  "api.openverse.engineering",
39                  gethostname(), gethostbyname(gethostname())]
40 
41 # Domains that shortened links may point to
42 SHORT_URL_WHITELIST = {
43     'api-dev.openverse.engineering',
44     'api.openverse.engineering',
45     'localhost:8000'
46 }
47 SHORT_URL_PATH_WHITELIST = ['/v1/list', '/v1/images/']
48 
49 USE_S3 = os.getenv('USE_S3', False)
50 
51 # Application definition
52 
53 INSTALLED_APPS = [
54     'catalog',
55     'catalog.api',
56     'drf_yasg',
57     'django.contrib.admin',
58     'django.contrib.auth',
59     'django.contrib.contenttypes',
60     'django.contrib.sessions',
61     'django.contrib.messages',
62     'django.contrib.staticfiles',
63     'oauth2_provider',
64     'rest_framework',
65     'corsheaders',
66     'sslserver',
67 ]
68 
69 if USE_S3:
70     DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
71     AWS_STORAGE_BUCKET_NAME = os.getenv(
72         'LOGOS_BUCKET', 'openverse-api-logos-prod'
73     )
74     AWS_S3_SIGNATURE_VERSION = 's3v4'
75     INSTALLED_APPS.append('storages')
76 
77 MIDDLEWARE = [
78     'django.middleware.security.SecurityMiddleware',
79     'django.contrib.sessions.middleware.SessionMiddleware',
80     'django.middleware.common.CommonMiddleware',
81     'django.middleware.csrf.CsrfViewMiddleware',
82     'django.contrib.auth.middleware.AuthenticationMiddleware',
83     'django.contrib.messages.middleware.MessageMiddleware',
84     'django.middleware.clickjacking.XFrameOptionsMiddleware',
85     'corsheaders.middleware.CorsMiddleware',
86     'oauth2_provider.middleware.OAuth2TokenMiddleware'
87 ]
88 
89 SWAGGER_SETTINGS = {
90     'SECURITY_DEFINITIONS': {}
91 }
92 
93 OAUTH2_PROVIDER = {
94     'SCOPES': {
95         'read': 'Read scope',
96         'write': 'Write scope',
97     }
98 }
99 
100 OAUTH2_PROVIDER_APPLICATION_MODEL = 'api.ThrottledApplication'
101 
102 REST_FRAMEWORK = {
103     'DEFAULT_AUTHENTICATION_CLASSES': (
104         'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
105     ),
106     'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',
107     'DEFAULT_RENDERER_CLASSES': (
108         'rest_framework.renderers.JSONRenderer',
109         'rest_framework.renderers.BrowsableAPIRenderer',
110         'rest_framework_xml.renderers.XMLRenderer',
111     ),
112     'DEFAULT_THROTTLE_CLASSES': (
113         'catalog.api.utils.throttle.BurstRateThrottle',
114         'catalog.api.utils.throttle.SustainedRateThrottle',
115         'catalog.api.utils.throttle.OAuth2IdThrottleSustainedRate',
116         'catalog.api.utils.throttle.OAuth2IdThrottleBurstRate',
117         'catalog.api.utils.throttle.EnhancedOAuth2IdThrottleSustainedRate',
118         'catalog.api.utils.throttle.EnhancedOAuth2IdThrottleBurstRate'
119     ),
120     'DEFAULT_THROTTLE_RATES': {
121         'anon_burst': '60/min',
122         'anon_sustained': '5000/day',
123         'oauth2_client_credentials_sustained': '10000/day',
124         'oauth2_client_credentials_burst': '100/min',
125         'enhanced_oauth2_client_credentials_sustained': '20000/day',
126         'enhanced_oauth2_client_credentials_burst': '200/min'
127     },
128 }
129 
130 if os.environ.get('DISABLE_GLOBAL_THROTTLING', default=False) in true_strings:
131     del REST_FRAMEWORK['DEFAULT_THROTTLE_RATES']
132     del REST_FRAMEWORK['DEFAULT_THROTTLE_CLASSES']
133 
134 REDIS_HOST = os.environ.get('REDIS_HOST', 'cache')
135 CACHES = {
136     # Site cache writes to 'default'
137     "default": {
138         "BACKEND": "django_redis.cache.RedisCache",
139         "LOCATION": 'redis://' + REDIS_HOST + ':6379/' + '0',
140         "OPTIONS": {
141             "CLIENT_CLASS": "django_redis.client.DefaultClient",
142         },
143     },
144     # For rapidly changing stats that we don't want to hammer the database with
145     "traffic_stats": {
146         "BACKEND": "django_redis.cache.RedisCache",
147         "LOCATION": 'redis://' + REDIS_HOST + ':6379/' + '1',
148         "OPTIONS": {
149             "CLIENT_CLASS": "django_redis.client.DefaultClient",
150         },
151     },
152     # For ensuring consistency among multiple Django workers and servers.
153     # Used by Redlock.
154     "locks": {
155         "BACKEND": "django_redis.cache.RedisCache",
156         "LOCATION": 'redis://' + REDIS_HOST + ':6379/2',
157         "OPTIONS": {
158             "CLIENT_CLASS": "django_redis.client.DefaultClient",
159         },
160     }
161 }
162 
163 # Produce CC-hosted thumbnails dynamically through a proxy.
164 THUMBNAIL_PROXY_URL = os.environ.get(
165     'THUMBNAIL_PROXY_URL', 'http://localhost:8222'
166 )
167 # Proxy insecure HTTP images through our internal proxy.
168 DETAIL_PROXY_URL = os.environ.get(
169     'DETAIL_PROXY_URL', 'https://api.openverse.engineering/t'
170 )
171 
172 THUMBNAIL_WIDTH_PX = 600
173 
174 AUTHENTICATION_BACKENDS = (
175     'oauth2_provider.backends.OAuth2Backend',
176     'django.contrib.auth.backends.ModelBackend',
177 )
178 
179 ROOT_URLCONF = 'catalog.urls'
180 
181 TEMPLATES = [
182     {
183         'BACKEND': 'django.template.backends.django.DjangoTemplates',
184         'DIRS': [
185             BASE_DIR.joinpath('catalog', 'templates')
186         ],
187         'APP_DIRS': True,
188         'OPTIONS': {
189             'context_processors': [
190                 'django.template.context_processors.debug',
191                 'django.template.context_processors.request',
192                 'django.contrib.auth.context_processors.auth',
193                 'django.contrib.messages.context_processors.messages',
194             ],
195         },
196     },
197 ]
198 
199 WSGI_APPLICATION = 'catalog.wsgi.application'
200 
201 # Database
202 # https://docs.djangoproject.com/en/2.0/ref/settings/#databases
203 
204 DATABASES = {
205     'default': {
206         'ENGINE': 'django.db.backends.postgresql',
207         'NAME': os.environ.get('DJANGO_DATABASE_NAME'),
208         'USER': os.environ.get('DJANGO_DATABASE_USER'),
209         'PASSWORD': os.environ.get('DJANGO_DATABASE_PASSWORD'),
210         'HOST': os.environ.get('DJANGO_DATABASE_HOST'),
211         'PORT': os.environ.get('DJANGO_DATABASE_PORT'),
212     },
213     'upstream': {
214         'ENGINE': 'django.db.backends.postgresql',
215         'NAME': os.environ.get('DJANGO_DATABASE_NAME'),
216         'USER': os.environ.get('DJANGO_DATABASE_USER'),
217         'PASSWORD': os.environ.get('UPSTREAM_DATABASE_PASSWORD', 'deploy'),
218         'HOST': os.environ.get('UPSTREAM_DATABASE_HOST'),
219         'PORT': os.environ.get('DJANGO_DATABASE_PORT'),
220     }
221 }
222 
223 # Password validation
224 # https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators
225 
226 AUTH_PASSWORD_VALIDATORS = [
227     {
228         'NAME': 'django.contrib.auth.password_validation'
229                 '.UserAttributeSimilarityValidator',
230     },
231     {
232         'NAME': 'django.contrib.auth.password_validation'
233                 '.MinimumLengthValidator',
234     },
235     {
236         'NAME': 'django.contrib.auth.password_validation'
237                 '.CommonPasswordValidator',
238     },
239     {
240         'NAME': 'django.contrib.auth.password_validation'
241                 '.NumericPasswordValidator',
242     },
243 ]
244 
245 LOGGING = {
246     'version': 1,
247     'disable_existing_loggers': False,
248     'handlers': {
249         'console': {
250             'level': 'INFO',
251             'class': 'logging.StreamHandler',
252         },
253     },
254     'loggers': {
255         'django': {
256             'handlers': ['console'],
257             'level': 'INFO',
258             'propagate': True,
259         },
260         # root logger
261         '': {
262             'level': 'INFO',
263             'handlers': ['console'],
264         },
265     }
266 }
267 
268 # Internationalization
269 # https://docs.djangoproject.com/en/2.0/topics/i18n/
270 
271 LANGUAGE_CODE = 'en-us'
272 
273 TIME_ZONE = 'UTC'
274 
275 USE_I18N = True
276 
277 USE_L10N = True
278 
279 USE_TZ = True
280 
281 # Static files (CSS, JavaScript, Images)
282 # https://docs.djangoproject.com/en/2.0/howto/static-files/
283 
284 STATIC_URL = '/static/'
285 
286 # Allow anybody to access the API from any domain
287 CORS_ORIGIN_ALLOW_ALL = True
288 
289 # The version of the API. We follow the semantic version specification.
290 API_VERSION = os.environ.get(
291     'SEMANTIC_VERSION',
292     "Version not specified."
293 )
294 
295 WATERMARK_ENABLED = os.environ.get('WATERMARK_ENABLED', 'false') in true_strings
296 
297 ELASTICSEARCH_URL = os.environ.get('ELASTICSEARCH_URL', 'localhost')
298 ELASTICSEARCH_PORT = int(os.environ.get('ELASTICSEARCH_PORT', 9200))
299 
300 # Additional settings for dev/prod environments
301 AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID', '')
302 AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY', '')
303 ELASTICSEARCH_AWS_REGION = \
304     os.environ.get('ELASTICSEARCH_AWS_REGION', 'us-east-1')
305 
306 ROOT_SHORTENING_URL = os.environ.get('ROOT_SHORTENING_URL', 'dev.shares.cc')
307 
308 EMAIL_HOST = os.environ.get('EMAIL_HOST', '')
309 EMAIL_PORT = os.environ.get('EMAIL_PORT', 25)
310 EMAIL_HOST_USER = os.environ.get('EMAIL_HOST_USER', '')
311 EMAIL_HOST_PASSWORD = os.environ.get('EMAIL_HOST_PASSWORD', '')
312 EMAIL_SUBJECT_PREFIX = '[noreply]'
313 EMAIL_USE_TLS = True
314 
315 if EMAIL_HOST_USER or EMAIL_HOST_PASSWORD:
316     EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
317 else:
318     EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
319 
320 # Log full Elasticsearch response
321 VERBOSE_ES_RESPONSE = os.getenv('DEBUG_SCORES', 'False') in true_strings
322 
323 # Whether to boost results by authority and popularity
324 USE_RANK_FEATURES = os.getenv('USE_RANK_FEATURES', 'True') in true_strings
325
```
--- 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/openverse-api/catalog/settings.py b/openverse-api/catalog/settings.py
--- a/openverse-api/catalog/settings.py
+++ b/openverse-api/catalog/settings.py
@@ -77,12 +77,12 @@
 MIDDLEWARE = [
     'django.middleware.security.SecurityMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
+    'corsheaders.middleware.CorsMiddleware',
     'django.middleware.common.CommonMiddleware',
     'django.middleware.csrf.CsrfViewMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
     'django.middleware.clickjacking.XFrameOptionsMiddleware',
-    'corsheaders.middleware.CorsMiddleware',
     'oauth2_provider.middleware.OAuth2TokenMiddleware'
 ]

{"golden_diff": "diff --git a/openverse-api/catalog/settings.py b/openverse-api/catalog/settings.py\n--- a/openverse-api/catalog/settings.py\n+++ b/openverse-api/catalog/settings.py\n@@ -77,12 +77,12 @@\n MIDDLEWARE = [\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-    'corsheaders.middleware.CorsMiddleware',\n     'oauth2_provider.middleware.OAuth2TokenMiddleware'\n ]\n", "issue": "[Bug] API not adding CORS headers to responses\n## Description\r\n<!-- Concisely describe the bug. -->\r\nWhen trying to use the API locally with the Frontend project I got the following message in the browser's console:\r\n\r\n> Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8000/v1/images?q=birds. (Reason: CORS header \u2018Access-Control-Allow-Origin\u2019 missing).\r\n\r\nThis is from Firefox but a very similar one will show in Chrome too, preventing to get any useful response.\r\n\r\n## Reproduction\r\n<!-- Provide detailed steps to reproduce the bug. -->\r\n1. Run this project normally (instructions in README)\r\n2. Simultaneously, run the [Frontend][ov-fe] project using the local API\r\n```bash\r\nAPI_URL=http://localhost:8000/v1/ npm run dev\r\n```\r\n3. Open the browser and try to search anything\r\n4. See error.\r\n\r\n\r\n## Expectation\r\n<!-- Concisely describe what you expected to happen. -->\r\nIt should be possible to access the API from any domain, as [_is already intended_][ov-api-config], but a slightly misconfiguration is impeding.\r\n\r\n\r\n## Screenshots\r\n<!-- Add screenshots to show the problem; or delete the section entirely. -->\r\n\r\n<img width=\"814\" alt=\"Screen Shot 2021-08-25 at 7 17 32 PM\" src=\"https://user-images.githubusercontent.com/9145885/130876641-1e2f13ac-2717-4ce1-a555-46aa94133967.png\">\r\n\r\n\r\n[ov-fe]: https://github.com/WordPress/openverse-frontend\r\n[ov-api-config]: https://github.com/WordPress/openverse-api/blob/main/openverse-api/catalog/settings.py#L286:L287\r\n\r\n## Resolution\r\n<!-- Replace the [ ] with [x] to check the box. -->\r\n- [x] \ud83d\ude4b I would be interested in resolving this bug.\r\n\n", "before_files": [{"content": "\"\"\"\nDjango settings for catalog project.\n\nGenerated by 'django-admin startproject' using Django 2.0.5.\n\nFor more information on this file, see\nhttps://docs.djangoproject.com/en/2.0/topics/settings/\n\nFor the full list of settings and their values, see\nhttps://docs.djangoproject.com/en/2.0/ref/settings/\n\"\"\"\nimport os\nfrom pathlib import Path\nfrom socket import gethostname, gethostbyname\ntrue_strings = ['true', 'True', 't', '1']\n\n# Build paths inside the project like this: BASE_DIR.join('dir', 'subdir'...)\nBASE_DIR = Path(__file__).resolve().parent.parent\n\n# Where to collect static files in production/development deployments\nSTATIC_ROOT = \"/var/api_static_content/static\"\n\n# Logo uploads\nMEDIA_ROOT = '/var/api_media/'\nMEDIA_URL = '/media/'\n\n# Quick-start development settings - unsuitable for production\n# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/\n\n# SECURITY WARNING: keep the secret key used in production secret!\nSECRET_KEY = os.environ.get('DJANGO_SECRET_KEY')\n\n# SECURITY WARNING: don't run with debug turned on in production!\nDEBUG = os.environ.get('DJANGO_DEBUG_ENABLED', default=False) in true_strings\n\nALLOWED_HOSTS = ['localhost', '127.0.0.1', os.environ.get('LOAD_BALANCER_URL'),\n                 'api-dev.openverse.engineering',\n                 \"api.openverse.engineering\",\n                 gethostname(), gethostbyname(gethostname())]\n\n# Domains that shortened links may point to\nSHORT_URL_WHITELIST = {\n    'api-dev.openverse.engineering',\n    'api.openverse.engineering',\n    'localhost:8000'\n}\nSHORT_URL_PATH_WHITELIST = ['/v1/list', '/v1/images/']\n\nUSE_S3 = os.getenv('USE_S3', False)\n\n# Application definition\n\nINSTALLED_APPS = [\n    'catalog',\n    'catalog.api',\n    'drf_yasg',\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    'oauth2_provider',\n    'rest_framework',\n    'corsheaders',\n    'sslserver',\n]\n\nif USE_S3:\n    DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'\n    AWS_STORAGE_BUCKET_NAME = os.getenv(\n        'LOGOS_BUCKET', 'openverse-api-logos-prod'\n    )\n    AWS_S3_SIGNATURE_VERSION = 's3v4'\n    INSTALLED_APPS.append('storages')\n\nMIDDLEWARE = [\n    'django.middleware.security.SecurityMiddleware',\n    'django.contrib.sessions.middleware.SessionMiddleware',\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    'corsheaders.middleware.CorsMiddleware',\n    'oauth2_provider.middleware.OAuth2TokenMiddleware'\n]\n\nSWAGGER_SETTINGS = {\n    'SECURITY_DEFINITIONS': {}\n}\n\nOAUTH2_PROVIDER = {\n    'SCOPES': {\n        'read': 'Read scope',\n        'write': 'Write scope',\n    }\n}\n\nOAUTH2_PROVIDER_APPLICATION_MODEL = 'api.ThrottledApplication'\n\nREST_FRAMEWORK = {\n    'DEFAULT_AUTHENTICATION_CLASSES': (\n        'oauth2_provider.contrib.rest_framework.OAuth2Authentication',\n    ),\n    'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',\n    'DEFAULT_RENDERER_CLASSES': (\n        'rest_framework.renderers.JSONRenderer',\n        'rest_framework.renderers.BrowsableAPIRenderer',\n        'rest_framework_xml.renderers.XMLRenderer',\n    ),\n    'DEFAULT_THROTTLE_CLASSES': (\n        'catalog.api.utils.throttle.BurstRateThrottle',\n        'catalog.api.utils.throttle.SustainedRateThrottle',\n        'catalog.api.utils.throttle.OAuth2IdThrottleSustainedRate',\n        'catalog.api.utils.throttle.OAuth2IdThrottleBurstRate',\n        'catalog.api.utils.throttle.EnhancedOAuth2IdThrottleSustainedRate',\n        'catalog.api.utils.throttle.EnhancedOAuth2IdThrottleBurstRate'\n    ),\n    'DEFAULT_THROTTLE_RATES': {\n        'anon_burst': '60/min',\n        'anon_sustained': '5000/day',\n        'oauth2_client_credentials_sustained': '10000/day',\n        'oauth2_client_credentials_burst': '100/min',\n        'enhanced_oauth2_client_credentials_sustained': '20000/day',\n        'enhanced_oauth2_client_credentials_burst': '200/min'\n    },\n}\n\nif os.environ.get('DISABLE_GLOBAL_THROTTLING', default=False) in true_strings:\n    del REST_FRAMEWORK['DEFAULT_THROTTLE_RATES']\n    del REST_FRAMEWORK['DEFAULT_THROTTLE_CLASSES']\n\nREDIS_HOST = os.environ.get('REDIS_HOST', 'cache')\nCACHES = {\n    # Site cache writes to 'default'\n    \"default\": {\n        \"BACKEND\": \"django_redis.cache.RedisCache\",\n        \"LOCATION\": 'redis://' + REDIS_HOST + ':6379/' + '0',\n        \"OPTIONS\": {\n            \"CLIENT_CLASS\": \"django_redis.client.DefaultClient\",\n        },\n    },\n    # For rapidly changing stats that we don't want to hammer the database with\n    \"traffic_stats\": {\n        \"BACKEND\": \"django_redis.cache.RedisCache\",\n        \"LOCATION\": 'redis://' + REDIS_HOST + ':6379/' + '1',\n        \"OPTIONS\": {\n            \"CLIENT_CLASS\": \"django_redis.client.DefaultClient\",\n        },\n    },\n    # For ensuring consistency among multiple Django workers and servers.\n    # Used by Redlock.\n    \"locks\": {\n        \"BACKEND\": \"django_redis.cache.RedisCache\",\n        \"LOCATION\": 'redis://' + REDIS_HOST + ':6379/2',\n        \"OPTIONS\": {\n            \"CLIENT_CLASS\": \"django_redis.client.DefaultClient\",\n        },\n    }\n}\n\n# Produce CC-hosted thumbnails dynamically through a proxy.\nTHUMBNAIL_PROXY_URL = os.environ.get(\n    'THUMBNAIL_PROXY_URL', 'http://localhost:8222'\n)\n# Proxy insecure HTTP images through our internal proxy.\nDETAIL_PROXY_URL = os.environ.get(\n    'DETAIL_PROXY_URL', 'https://api.openverse.engineering/t'\n)\n\nTHUMBNAIL_WIDTH_PX = 600\n\nAUTHENTICATION_BACKENDS = (\n    'oauth2_provider.backends.OAuth2Backend',\n    'django.contrib.auth.backends.ModelBackend',\n)\n\nROOT_URLCONF = 'catalog.urls'\n\nTEMPLATES = [\n    {\n        'BACKEND': 'django.template.backends.django.DjangoTemplates',\n        'DIRS': [\n            BASE_DIR.joinpath('catalog', 'templates')\n        ],\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 = 'catalog.wsgi.application'\n\n# Database\n# https://docs.djangoproject.com/en/2.0/ref/settings/#databases\n\nDATABASES = {\n    'default': {\n        'ENGINE': 'django.db.backends.postgresql',\n        'NAME': os.environ.get('DJANGO_DATABASE_NAME'),\n        'USER': os.environ.get('DJANGO_DATABASE_USER'),\n        'PASSWORD': os.environ.get('DJANGO_DATABASE_PASSWORD'),\n        'HOST': os.environ.get('DJANGO_DATABASE_HOST'),\n        'PORT': os.environ.get('DJANGO_DATABASE_PORT'),\n    },\n    'upstream': {\n        'ENGINE': 'django.db.backends.postgresql',\n        'NAME': os.environ.get('DJANGO_DATABASE_NAME'),\n        'USER': os.environ.get('DJANGO_DATABASE_USER'),\n        'PASSWORD': os.environ.get('UPSTREAM_DATABASE_PASSWORD', 'deploy'),\n        'HOST': os.environ.get('UPSTREAM_DATABASE_HOST'),\n        'PORT': os.environ.get('DJANGO_DATABASE_PORT'),\n    }\n}\n\n# Password validation\n# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators\n\nAUTH_PASSWORD_VALIDATORS = [\n    {\n        'NAME': 'django.contrib.auth.password_validation'\n                '.UserAttributeSimilarityValidator',\n    },\n    {\n        'NAME': 'django.contrib.auth.password_validation'\n                '.MinimumLengthValidator',\n    },\n    {\n        'NAME': 'django.contrib.auth.password_validation'\n                '.CommonPasswordValidator',\n    },\n    {\n        'NAME': 'django.contrib.auth.password_validation'\n                '.NumericPasswordValidator',\n    },\n]\n\nLOGGING = {\n    'version': 1,\n    'disable_existing_loggers': False,\n    'handlers': {\n        'console': {\n            'level': 'INFO',\n            'class': 'logging.StreamHandler',\n        },\n    },\n    'loggers': {\n        'django': {\n            'handlers': ['console'],\n            'level': 'INFO',\n            'propagate': True,\n        },\n        # root logger\n        '': {\n            'level': 'INFO',\n            'handlers': ['console'],\n        },\n    }\n}\n\n# Internationalization\n# https://docs.djangoproject.com/en/2.0/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# Static files (CSS, JavaScript, Images)\n# https://docs.djangoproject.com/en/2.0/howto/static-files/\n\nSTATIC_URL = '/static/'\n\n# Allow anybody to access the API from any domain\nCORS_ORIGIN_ALLOW_ALL = True\n\n# The version of the API. We follow the semantic version specification.\nAPI_VERSION = os.environ.get(\n    'SEMANTIC_VERSION',\n    \"Version not specified.\"\n)\n\nWATERMARK_ENABLED = os.environ.get('WATERMARK_ENABLED', 'false') in true_strings\n\nELASTICSEARCH_URL = os.environ.get('ELASTICSEARCH_URL', 'localhost')\nELASTICSEARCH_PORT = int(os.environ.get('ELASTICSEARCH_PORT', 9200))\n\n# Additional settings for dev/prod environments\nAWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID', '')\nAWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY', '')\nELASTICSEARCH_AWS_REGION = \\\n    os.environ.get('ELASTICSEARCH_AWS_REGION', 'us-east-1')\n\nROOT_SHORTENING_URL = os.environ.get('ROOT_SHORTENING_URL', 'dev.shares.cc')\n\nEMAIL_HOST = os.environ.get('EMAIL_HOST', '')\nEMAIL_PORT = os.environ.get('EMAIL_PORT', 25)\nEMAIL_HOST_USER = os.environ.get('EMAIL_HOST_USER', '')\nEMAIL_HOST_PASSWORD = os.environ.get('EMAIL_HOST_PASSWORD', '')\nEMAIL_SUBJECT_PREFIX = '[noreply]'\nEMAIL_USE_TLS = True\n\nif EMAIL_HOST_USER or EMAIL_HOST_PASSWORD:\n    EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'\nelse:\n    EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'\n\n# Log full Elasticsearch response\nVERBOSE_ES_RESPONSE = os.getenv('DEBUG_SCORES', 'False') in true_strings\n\n# Whether to boost results by authority and popularity\nUSE_RANK_FEATURES = os.getenv('USE_RANK_FEATURES', 'True') in true_strings\n", "path": "openverse-api/catalog/settings.py"}], "after_files": [{"content": "\"\"\"\nDjango settings for catalog project.\n\nGenerated by 'django-admin startproject' using Django 2.0.5.\n\nFor more information on this file, see\nhttps://docs.djangoproject.com/en/2.0/topics/settings/\n\nFor the full list of settings and their values, see\nhttps://docs.djangoproject.com/en/2.0/ref/settings/\n\"\"\"\nimport os\nfrom pathlib import Path\nfrom socket import gethostname, gethostbyname\ntrue_strings = ['true', 'True', 't', '1']\n\n# Build paths inside the project like this: BASE_DIR.join('dir', 'subdir'...)\nBASE_DIR = Path(__file__).resolve().parent.parent\n\n# Where to collect static files in production/development deployments\nSTATIC_ROOT = \"/var/api_static_content/static\"\n\n# Logo uploads\nMEDIA_ROOT = '/var/api_media/'\nMEDIA_URL = '/media/'\n\n# Quick-start development settings - unsuitable for production\n# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/\n\n# SECURITY WARNING: keep the secret key used in production secret!\nSECRET_KEY = os.environ.get('DJANGO_SECRET_KEY')\n\n# SECURITY WARNING: don't run with debug turned on in production!\nDEBUG = os.environ.get('DJANGO_DEBUG_ENABLED', default=False) in true_strings\n\nALLOWED_HOSTS = ['localhost', '127.0.0.1', os.environ.get('LOAD_BALANCER_URL'),\n                 'api-dev.openverse.engineering',\n                 \"api.openverse.engineering\",\n                 gethostname(), gethostbyname(gethostname())]\n\n# Domains that shortened links may point to\nSHORT_URL_WHITELIST = {\n    'api-dev.openverse.engineering',\n    'api.openverse.engineering',\n    'localhost:8000'\n}\nSHORT_URL_PATH_WHITELIST = ['/v1/list', '/v1/images/']\n\nUSE_S3 = os.getenv('USE_S3', False)\n\n# Application definition\n\nINSTALLED_APPS = [\n    'catalog',\n    'catalog.api',\n    'drf_yasg',\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    'oauth2_provider',\n    'rest_framework',\n    'corsheaders',\n    'sslserver',\n]\n\nif USE_S3:\n    DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'\n    AWS_STORAGE_BUCKET_NAME = os.getenv(\n        'LOGOS_BUCKET', 'openverse-api-logos-prod'\n    )\n    AWS_S3_SIGNATURE_VERSION = 's3v4'\n    INSTALLED_APPS.append('storages')\n\nMIDDLEWARE = [\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    'oauth2_provider.middleware.OAuth2TokenMiddleware'\n]\n\nSWAGGER_SETTINGS = {\n    'SECURITY_DEFINITIONS': {}\n}\n\nOAUTH2_PROVIDER = {\n    'SCOPES': {\n        'read': 'Read scope',\n        'write': 'Write scope',\n    }\n}\n\nOAUTH2_PROVIDER_APPLICATION_MODEL = 'api.ThrottledApplication'\n\nREST_FRAMEWORK = {\n    'DEFAULT_AUTHENTICATION_CLASSES': (\n        'oauth2_provider.contrib.rest_framework.OAuth2Authentication',\n    ),\n    'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',\n    'DEFAULT_RENDERER_CLASSES': (\n        'rest_framework.renderers.JSONRenderer',\n        'rest_framework.renderers.BrowsableAPIRenderer',\n        'rest_framework_xml.renderers.XMLRenderer',\n    ),\n    'DEFAULT_THROTTLE_CLASSES': (\n        'catalog.api.utils.throttle.BurstRateThrottle',\n        'catalog.api.utils.throttle.SustainedRateThrottle',\n        'catalog.api.utils.throttle.OAuth2IdThrottleSustainedRate',\n        'catalog.api.utils.throttle.OAuth2IdThrottleBurstRate',\n        'catalog.api.utils.throttle.EnhancedOAuth2IdThrottleSustainedRate',\n        'catalog.api.utils.throttle.EnhancedOAuth2IdThrottleBurstRate'\n    ),\n    'DEFAULT_THROTTLE_RATES': {\n        'anon_burst': '60/min',\n        'anon_sustained': '5000/day',\n        'oauth2_client_credentials_sustained': '10000/day',\n        'oauth2_client_credentials_burst': '100/min',\n        'enhanced_oauth2_client_credentials_sustained': '20000/day',\n        'enhanced_oauth2_client_credentials_burst': '200/min'\n    },\n}\n\nif os.environ.get('DISABLE_GLOBAL_THROTTLING', default=False) in true_strings:\n    del REST_FRAMEWORK['DEFAULT_THROTTLE_RATES']\n    del REST_FRAMEWORK['DEFAULT_THROTTLE_CLASSES']\n\nREDIS_HOST = os.environ.get('REDIS_HOST', 'cache')\nCACHES = {\n    # Site cache writes to 'default'\n    \"default\": {\n        \"BACKEND\": \"django_redis.cache.RedisCache\",\n        \"LOCATION\": 'redis://' + REDIS_HOST + ':6379/' + '0',\n        \"OPTIONS\": {\n            \"CLIENT_CLASS\": \"django_redis.client.DefaultClient\",\n        },\n    },\n    # For rapidly changing stats that we don't want to hammer the database with\n    \"traffic_stats\": {\n        \"BACKEND\": \"django_redis.cache.RedisCache\",\n        \"LOCATION\": 'redis://' + REDIS_HOST + ':6379/' + '1',\n        \"OPTIONS\": {\n            \"CLIENT_CLASS\": \"django_redis.client.DefaultClient\",\n        },\n    },\n    # For ensuring consistency among multiple Django workers and servers.\n    # Used by Redlock.\n    \"locks\": {\n        \"BACKEND\": \"django_redis.cache.RedisCache\",\n        \"LOCATION\": 'redis://' + REDIS_HOST + ':6379/2',\n        \"OPTIONS\": {\n            \"CLIENT_CLASS\": \"django_redis.client.DefaultClient\",\n        },\n    }\n}\n\n# Produce CC-hosted thumbnails dynamically through a proxy.\nTHUMBNAIL_PROXY_URL = os.environ.get(\n    'THUMBNAIL_PROXY_URL', 'http://localhost:8222'\n)\n# Proxy insecure HTTP images through our internal proxy.\nDETAIL_PROXY_URL = os.environ.get(\n    'DETAIL_PROXY_URL', 'https://api.openverse.engineering/t'\n)\n\nTHUMBNAIL_WIDTH_PX = 600\n\nAUTHENTICATION_BACKENDS = (\n    'oauth2_provider.backends.OAuth2Backend',\n    'django.contrib.auth.backends.ModelBackend',\n)\n\nROOT_URLCONF = 'catalog.urls'\n\nTEMPLATES = [\n    {\n        'BACKEND': 'django.template.backends.django.DjangoTemplates',\n        'DIRS': [\n            BASE_DIR.joinpath('catalog', 'templates')\n        ],\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 = 'catalog.wsgi.application'\n\n# Database\n# https://docs.djangoproject.com/en/2.0/ref/settings/#databases\n\nDATABASES = {\n    'default': {\n        'ENGINE': 'django.db.backends.postgresql',\n        'NAME': os.environ.get('DJANGO_DATABASE_NAME'),\n        'USER': os.environ.get('DJANGO_DATABASE_USER'),\n        'PASSWORD': os.environ.get('DJANGO_DATABASE_PASSWORD'),\n        'HOST': os.environ.get('DJANGO_DATABASE_HOST'),\n        'PORT': os.environ.get('DJANGO_DATABASE_PORT'),\n    },\n    'upstream': {\n        'ENGINE': 'django.db.backends.postgresql',\n        'NAME': os.environ.get('DJANGO_DATABASE_NAME'),\n        'USER': os.environ.get('DJANGO_DATABASE_USER'),\n        'PASSWORD': os.environ.get('UPSTREAM_DATABASE_PASSWORD', 'deploy'),\n        'HOST': os.environ.get('UPSTREAM_DATABASE_HOST'),\n        'PORT': os.environ.get('DJANGO_DATABASE_PORT'),\n    }\n}\n\n# Password validation\n# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators\n\nAUTH_PASSWORD_VALIDATORS = [\n    {\n        'NAME': 'django.contrib.auth.password_validation'\n                '.UserAttributeSimilarityValidator',\n    },\n    {\n        'NAME': 'django.contrib.auth.password_validation'\n                '.MinimumLengthValidator',\n    },\n    {\n        'NAME': 'django.contrib.auth.password_validation'\n                '.CommonPasswordValidator',\n    },\n    {\n        'NAME': 'django.contrib.auth.password_validation'\n                '.NumericPasswordValidator',\n    },\n]\n\nLOGGING = {\n    'version': 1,\n    'disable_existing_loggers': False,\n    'handlers': {\n        'console': {\n            'level': 'INFO',\n            'class': 'logging.StreamHandler',\n        },\n    },\n    'loggers': {\n        'django': {\n            'handlers': ['console'],\n            'level': 'INFO',\n            'propagate': True,\n        },\n        # root logger\n        '': {\n            'level': 'INFO',\n            'handlers': ['console'],\n        },\n    }\n}\n\n# Internationalization\n# https://docs.djangoproject.com/en/2.0/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# Static files (CSS, JavaScript, Images)\n# https://docs.djangoproject.com/en/2.0/howto/static-files/\n\nSTATIC_URL = '/static/'\n\n# Allow anybody to access the API from any domain\nCORS_ORIGIN_ALLOW_ALL = True\n\n# The version of the API. We follow the semantic version specification.\nAPI_VERSION = os.environ.get(\n    'SEMANTIC_VERSION',\n    \"Version not specified.\"\n)\n\nWATERMARK_ENABLED = os.environ.get('WATERMARK_ENABLED', 'false') in true_strings\n\nELASTICSEARCH_URL = os.environ.get('ELASTICSEARCH_URL', 'localhost')\nELASTICSEARCH_PORT = int(os.environ.get('ELASTICSEARCH_PORT', 9200))\n\n# Additional settings for dev/prod environments\nAWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID', '')\nAWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY', '')\nELASTICSEARCH_AWS_REGION = \\\n    os.environ.get('ELASTICSEARCH_AWS_REGION', 'us-east-1')\n\nROOT_SHORTENING_URL = os.environ.get('ROOT_SHORTENING_URL', 'dev.shares.cc')\n\nEMAIL_HOST = os.environ.get('EMAIL_HOST', '')\nEMAIL_PORT = os.environ.get('EMAIL_PORT', 25)\nEMAIL_HOST_USER = os.environ.get('EMAIL_HOST_USER', '')\nEMAIL_HOST_PASSWORD = os.environ.get('EMAIL_HOST_PASSWORD', '')\nEMAIL_SUBJECT_PREFIX = '[noreply]'\nEMAIL_USE_TLS = True\n\nif EMAIL_HOST_USER or EMAIL_HOST_PASSWORD:\n    EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'\nelse:\n    EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'\n\n# Log full Elasticsearch response\nVERBOSE_ES_RESPONSE = os.getenv('DEBUG_SCORES', 'False') in true_strings\n\n# Whether to boost results by authority and popularity\nUSE_RANK_FEATURES = os.getenv('USE_RANK_FEATURES', 'True') in true_strings\n", "path": "openverse-api/catalog/settings.py"}]}