We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Replace PYTHON_ENV with ENVIRONMENT
## Description
<!-- Concisely describe the bug. -->
Our deployment infrastructure already configures an `ENVIRONMENT` variable and it is already used in the ingestion server code. Rather than introduce a new one that duplicates that, we can just use that everywhere.

Making this change will solve the issue we're seeing Sentry where staging is reporting itself as `production`.

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

{"golden_diff": "diff --git a/api/catalog/settings.py b/api/catalog/settings.py\n--- a/api/catalog/settings.py\n+++ b/api/catalog/settings.py\n@@ -39,7 +39,7 @@\n # SECURITY WARNING: don't run with debug turned on in production!\n DEBUG = config(\"DJANGO_DEBUG_ENABLED\", default=False, cast=bool)\n \n-PYTHON_ENV = config(\"PYTHON_ENV\", default=\"production\")\n+ENVIRONMENT = config(\"ENVIRONMENT\", default=\"local\")\n \n ALLOWED_HOSTS = [\n     \"api-dev.openverse.engineering\",\n@@ -318,5 +318,5 @@\n         integrations=[DjangoIntegration()],\n         traces_sample_rate=SENTRY_SAMPLE_RATE,\n         send_default_pii=False,\n-        environment=PYTHON_ENV,\n+        environment=ENVIRONMENT,\n     )\n", "issue": "Replace PYTHON_ENV with ENVIRONMENT\n## Description\r\n<!-- Concisely describe the bug. -->\r\nOur deployment infrastructure already configures an `ENVIRONMENT` variable and it is already used in the ingestion server code. Rather than introduce a new one that duplicates that, we can just use that everywhere.\r\n\r\nMaking this change will solve the issue we're seeing Sentry where staging is reporting itself as `production`.\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\"\"\"\n\nfrom pathlib import Path\nfrom socket import gethostbyname, gethostname\n\nimport sentry_sdk\nfrom decouple import config\nfrom sentry_sdk.integrations.django import DjangoIntegration\n\nfrom .logger import LOGGING  # noqa: F401\n\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 = config(\"DJANGO_SECRET_KEY\")  # required\n\n# SECURITY WARNING: don't run with debug turned on in production!\nDEBUG = config(\"DJANGO_DEBUG_ENABLED\", default=False, cast=bool)\n\nPYTHON_ENV = config(\"PYTHON_ENV\", default=\"production\")\n\nALLOWED_HOSTS = [\n    \"api-dev.openverse.engineering\",\n    \"api.openverse.engineering\",\n    gethostname(),\n    gethostbyname(gethostname()),\n]\n\nif lb_url := config(\"LOAD_BALANCER_URL\", default=\"\"):\n    ALLOWED_HOSTS.append(lb_url)\n\nif DEBUG:\n    ALLOWED_HOSTS += [\n        \"localhost\",\n        \"127.0.0.1\",\n        \"0.0.0.0\",\n    ]\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 = config(\"USE_S3\", default=False, cast=bool)\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 = config(\"LOGOS_BUCKET\", default=\"openverse_api-logos-prod\")\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 = {\"SECURITY_DEFINITIONS\": {}}\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    \"EXCEPTION_HANDLER\": \"catalog.api.utils.exceptions.exception_handler\",\n}\n\nif config(\"DISABLE_GLOBAL_THROTTLING\", default=True, cast=bool):\n    del REST_FRAMEWORK[\"DEFAULT_THROTTLE_RATES\"]\n    del REST_FRAMEWORK[\"DEFAULT_THROTTLE_CLASSES\"]\n\nREDIS_HOST = config(\"REDIS_HOST\", default=\"localhost\")\nREDIS_PORT = config(\"REDIS_PORT\", default=6379, cast=int)\nREDIS_PASSWORD = config(\"REDIS_PASSWORD\", default=\"\")\nCACHES = {\n    # Site cache writes to 'default'\n    \"default\": {\n        \"BACKEND\": \"django_redis.cache.RedisCache\",\n        \"LOCATION\": f\"redis://{REDIS_HOST}:{REDIS_PORT}/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\": f\"redis://{REDIS_HOST}:{REDIS_PORT}/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\": f\"redis://{REDIS_HOST}:{REDIS_PORT}/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 = config(\"THUMBNAIL_PROXY_URL\", default=\"http://localhost:8222\")\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\": [BASE_DIR.joinpath(\"catalog\", \"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 = \"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        \"HOST\": config(\"DJANGO_DATABASE_HOST\", default=\"localhost\"),\n        \"PORT\": config(\"DJANGO_DATABASE_PORT\", default=5432, cast=int),\n        \"USER\": config(\"DJANGO_DATABASE_USER\", default=\"deploy\"),\n        \"PASSWORD\": config(\"DJANGO_DATABASE_PASSWORD\", default=\"deploy\"),\n        \"NAME\": config(\"DJANGO_DATABASE_NAME\", default=\"openledger\"),\n    },\n    \"upstream\": {\n        \"ENGINE\": \"django.db.backends.postgresql\",\n        \"HOST\": config(\"UPSTREAM_DATABASE_HOST\", default=\"localhost\"),\n        \"PORT\": config(\"UPSTREAM_DATABASE_PORT\", default=5433, cast=int),\n        \"USER\": config(\"UPSTREAM_DATABASE_USER\", default=\"deploy\"),\n        \"PASSWORD\": config(\"UPSTREAM_DATABASE_PASSWORD\", default=\"deploy\"),\n        \"NAME\": config(\"UPSTREAM_DATABASE_NAME\", default=\"openledger\"),\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\" \".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# 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 = config(\"SEMANTIC_VERSION\", default=\"Version not specified\")\n\n# The contact email of the Openverse team\nCONTACT_EMAIL = config(\"CONTACT_EMAIL\", default=\"openverse@wordpress.org\")\n\nWATERMARK_ENABLED = config(\"WATERMARK_ENABLED\", default=False, cast=bool)\n\nELASTICSEARCH_URL = config(\"ELASTICSEARCH_URL\", default=\"localhost\")\nELASTICSEARCH_PORT = config(\"ELASTICSEARCH_PORT\", default=9200, cast=int)\nELASTICSEARCH_AWS_REGION = config(\"ELASTICSEARCH_AWS_REGION\", default=\"us-east-1\")\n\n# Additional settings for dev/prod environments\nAWS_ACCESS_KEY_ID = config(\"AWS_ACCESS_KEY_ID\", default=\"\")\nAWS_SECRET_ACCESS_KEY = config(\"AWS_SECRET_ACCESS_KEY\", default=\"\")\n\nEMAIL_SENDER = config(\"EMAIL_SENDER\", default=\"\")\nEMAIL_HOST = config(\"EMAIL_HOST\", default=\"\")\nEMAIL_PORT = config(\"EMAIL_PORT\", default=25, cast=int)\nEMAIL_HOST_USER = config(\"EMAIL_HOST_USER\", default=\"\")\nEMAIL_HOST_PASSWORD = config(\"EMAIL_HOST_PASSWORD\", default=\"\")\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 = config(\"DEBUG_SCORES\", default=False, cast=bool)\n\n# Whether to boost results by authority and popularity\nUSE_RANK_FEATURES = config(\"USE_RANK_FEATURES\", default=True, cast=bool)\n\nSENTRY_DSN = config(\n    \"SENTRY_DSN\",\n    default=\"https://08f4706d16004f57bcd37eb907bfc2e7@o787041.ingest.sentry.io/6107216\",\n)\nSENTRY_SAMPLE_RATE = config(\"SENTRY_SAMPLE_RATE\", default=1.0, cast=float)\n\nif not DEBUG:\n    sentry_sdk.init(\n        dsn=SENTRY_DSN,\n        integrations=[DjangoIntegration()],\n        traces_sample_rate=SENTRY_SAMPLE_RATE,\n        send_default_pii=False,\n        environment=PYTHON_ENV,\n    )\n", "path": "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\"\"\"\n\nfrom pathlib import Path\nfrom socket import gethostbyname, gethostname\n\nimport sentry_sdk\nfrom decouple import config\nfrom sentry_sdk.integrations.django import DjangoIntegration\n\nfrom .logger import LOGGING  # noqa: F401\n\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 = config(\"DJANGO_SECRET_KEY\")  # required\n\n# SECURITY WARNING: don't run with debug turned on in production!\nDEBUG = config(\"DJANGO_DEBUG_ENABLED\", default=False, cast=bool)\n\nENVIRONMENT = config(\"ENVIRONMENT\", default=\"local\")\n\nALLOWED_HOSTS = [\n    \"api-dev.openverse.engineering\",\n    \"api.openverse.engineering\",\n    gethostname(),\n    gethostbyname(gethostname()),\n]\n\nif lb_url := config(\"LOAD_BALANCER_URL\", default=\"\"):\n    ALLOWED_HOSTS.append(lb_url)\n\nif DEBUG:\n    ALLOWED_HOSTS += [\n        \"localhost\",\n        \"127.0.0.1\",\n        \"0.0.0.0\",\n    ]\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 = config(\"USE_S3\", default=False, cast=bool)\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 = config(\"LOGOS_BUCKET\", default=\"openverse_api-logos-prod\")\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 = {\"SECURITY_DEFINITIONS\": {}}\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    \"EXCEPTION_HANDLER\": \"catalog.api.utils.exceptions.exception_handler\",\n}\n\nif config(\"DISABLE_GLOBAL_THROTTLING\", default=True, cast=bool):\n    del REST_FRAMEWORK[\"DEFAULT_THROTTLE_RATES\"]\n    del REST_FRAMEWORK[\"DEFAULT_THROTTLE_CLASSES\"]\n\nREDIS_HOST = config(\"REDIS_HOST\", default=\"localhost\")\nREDIS_PORT = config(\"REDIS_PORT\", default=6379, cast=int)\nREDIS_PASSWORD = config(\"REDIS_PASSWORD\", default=\"\")\nCACHES = {\n    # Site cache writes to 'default'\n    \"default\": {\n        \"BACKEND\": \"django_redis.cache.RedisCache\",\n        \"LOCATION\": f\"redis://{REDIS_HOST}:{REDIS_PORT}/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\": f\"redis://{REDIS_HOST}:{REDIS_PORT}/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\": f\"redis://{REDIS_HOST}:{REDIS_PORT}/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 = config(\"THUMBNAIL_PROXY_URL\", default=\"http://localhost:8222\")\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\": [BASE_DIR.joinpath(\"catalog\", \"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 = \"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        \"HOST\": config(\"DJANGO_DATABASE_HOST\", default=\"localhost\"),\n        \"PORT\": config(\"DJANGO_DATABASE_PORT\", default=5432, cast=int),\n        \"USER\": config(\"DJANGO_DATABASE_USER\", default=\"deploy\"),\n        \"PASSWORD\": config(\"DJANGO_DATABASE_PASSWORD\", default=\"deploy\"),\n        \"NAME\": config(\"DJANGO_DATABASE_NAME\", default=\"openledger\"),\n    },\n    \"upstream\": {\n        \"ENGINE\": \"django.db.backends.postgresql\",\n        \"HOST\": config(\"UPSTREAM_DATABASE_HOST\", default=\"localhost\"),\n        \"PORT\": config(\"UPSTREAM_DATABASE_PORT\", default=5433, cast=int),\n        \"USER\": config(\"UPSTREAM_DATABASE_USER\", default=\"deploy\"),\n        \"PASSWORD\": config(\"UPSTREAM_DATABASE_PASSWORD\", default=\"deploy\"),\n        \"NAME\": config(\"UPSTREAM_DATABASE_NAME\", default=\"openledger\"),\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\" \".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# 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 = config(\"SEMANTIC_VERSION\", default=\"Version not specified\")\n\n# The contact email of the Openverse team\nCONTACT_EMAIL = config(\"CONTACT_EMAIL\", default=\"openverse@wordpress.org\")\n\nWATERMARK_ENABLED = config(\"WATERMARK_ENABLED\", default=False, cast=bool)\n\nELASTICSEARCH_URL = config(\"ELASTICSEARCH_URL\", default=\"localhost\")\nELASTICSEARCH_PORT = config(\"ELASTICSEARCH_PORT\", default=9200, cast=int)\nELASTICSEARCH_AWS_REGION = config(\"ELASTICSEARCH_AWS_REGION\", default=\"us-east-1\")\n\n# Additional settings for dev/prod environments\nAWS_ACCESS_KEY_ID = config(\"AWS_ACCESS_KEY_ID\", default=\"\")\nAWS_SECRET_ACCESS_KEY = config(\"AWS_SECRET_ACCESS_KEY\", default=\"\")\n\nEMAIL_SENDER = config(\"EMAIL_SENDER\", default=\"\")\nEMAIL_HOST = config(\"EMAIL_HOST\", default=\"\")\nEMAIL_PORT = config(\"EMAIL_PORT\", default=25, cast=int)\nEMAIL_HOST_USER = config(\"EMAIL_HOST_USER\", default=\"\")\nEMAIL_HOST_PASSWORD = config(\"EMAIL_HOST_PASSWORD\", default=\"\")\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 = config(\"DEBUG_SCORES\", default=False, cast=bool)\n\n# Whether to boost results by authority and popularity\nUSE_RANK_FEATURES = config(\"USE_RANK_FEATURES\", default=True, cast=bool)\n\nSENTRY_DSN = config(\n    \"SENTRY_DSN\",\n    default=\"https://08f4706d16004f57bcd37eb907bfc2e7@o787041.ingest.sentry.io/6107216\",\n)\nSENTRY_SAMPLE_RATE = config(\"SENTRY_SAMPLE_RATE\", default=1.0, cast=float)\n\nif not DEBUG:\n    sentry_sdk.init(\n        dsn=SENTRY_DSN,\n        integrations=[DjangoIntegration()],\n        traces_sample_rate=SENTRY_SAMPLE_RATE,\n        send_default_pii=False,\n        environment=ENVIRONMENT,\n    )\n", "path": "api/catalog/settings.py"}]}