We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
SystemExit: 1
Sentry Issue: [SITE-1G](https://sentry.io/organizations/python-discord/issues/2623186847/?referrer=github_integration)

```
SystemExit: 1
(36 additional frame(s) were not displayed)
...
  File "urllib3/connectionpool.py", line 1010, in _validate_conn
    conn.connect()
  File "urllib3/connection.py", line 353, in connect
    conn = self._new_conn()
  File "urllib3/connection.py", line 169, in _new_conn
    conn = connection.create_connection(
  File "urllib3/util/connection.py", line 86, in create_connection
    sock.connect(sa)
  File "gunicorn/workers/base.py", line 201, in handle_abort
    sys.exit(1)
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pydis_site/constants.py`
Content:
```
1 import os
2 
3 GIT_SHA = os.environ.get("GIT_SHA", "development")
4 GITHUB_TOKEN = os.environ.get("GITHUB_TOKEN")
5
```

Path: `pydis_site/apps/home/views/home.py`
Content:
```
1 import logging
2 from typing import Dict, List
3 
4 import requests
5 from django.core.handlers.wsgi import WSGIRequest
6 from django.http import HttpResponse
7 from django.shortcuts import render
8 from django.utils import timezone
9 from django.views import View
10 
11 from pydis_site.apps.home.models import RepositoryMetadata
12 from pydis_site.constants import GITHUB_TOKEN
13 
14 log = logging.getLogger(__name__)
15 
16 
17 class HomeView(View):
18     """The main landing page for the website."""
19 
20     github_api = "https://api.github.com/users/python-discord/repos?per_page=100"
21     repository_cache_ttl = 3600
22 
23     # Which of our GitHub repos should be displayed on the front page, and in which order?
24     repos = [
25         "python-discord/site",
26         "python-discord/bot",
27         "python-discord/snekbox",
28         "python-discord/sir-lancebot",
29         "python-discord/metricity",
30         "python-discord/django-simple-bulma",
31     ]
32 
33     def __init__(self):
34         """Clean up stale RepositoryMetadata."""
35         RepositoryMetadata.objects.exclude(repo_name__in=self.repos).delete()
36 
37         # If no token is defined (for example in local development), then
38         # it does not make sense to pass the Authorization header. More
39         # specifically, GitHub will reject any requests from us due to the
40         # invalid header. We can make a limited number of anonymous requests
41         # though, which is useful for testing.
42         if GITHUB_TOKEN:
43             self.headers = {"Authorization": f"token {GITHUB_TOKEN}"}
44         else:
45             self.headers = {}
46 
47     def _get_api_data(self) -> Dict[str, Dict[str, str]]:
48         """
49         Call the GitHub API and get information about our repos.
50 
51         If we're unable to get that info for any reason, return an empty dict.
52         """
53         repo_dict = {}
54 
55         # Fetch the data from the GitHub API
56         api_data: List[dict] = requests.get(self.github_api, headers=self.headers).json()
57 
58         # Process the API data into our dict
59         for repo in api_data:
60             try:
61                 full_name = repo["full_name"]
62 
63                 if full_name in self.repos:
64                     repo_dict[full_name] = {
65                         "full_name": repo["full_name"],
66                         "description": repo["description"],
67                         "language": repo["language"],
68                         "forks_count": repo["forks_count"],
69                         "stargazers_count": repo["stargazers_count"],
70                     }
71             # Something is not right about the API data we got back from GitHub.
72             except (TypeError, ConnectionError, KeyError) as e:
73                 log.error(
74                     "Unable to parse the GitHub repository metadata from response!",
75                     extra={
76                         'api_data': api_data,
77                         'error': e
78                     }
79                 )
80                 continue
81 
82         return repo_dict
83 
84     def _get_repo_data(self) -> List[RepositoryMetadata]:
85         """Build a list of RepositoryMetadata objects that we can use to populate the front page."""
86         # First off, load the timestamp of the least recently updated entry.
87         last_update = (
88             RepositoryMetadata.objects.values_list("last_updated", flat=True)
89             .order_by("last_updated").first()
90         )
91 
92         # If we did not retrieve any results here, we should import them!
93         if last_update is None:
94 
95             # Try to get new data from the API. If it fails, we'll return an empty list.
96             # In this case, we simply don't display our projects on the site.
97             api_repositories = self._get_api_data()
98 
99             # Create all the repodata records in the database.
100             return RepositoryMetadata.objects.bulk_create(
101                 RepositoryMetadata(
102                     repo_name=api_data["full_name"],
103                     description=api_data["description"],
104                     forks=api_data["forks_count"],
105                     stargazers=api_data["stargazers_count"],
106                     language=api_data["language"],
107                 )
108                 for api_data in api_repositories.values()
109             )
110 
111         # If the data is stale, we should refresh it.
112         if (timezone.now() - last_update).seconds > self.repository_cache_ttl:
113             # Try to get new data from the API. If it fails, return the cached data.
114             api_repositories = self._get_api_data()
115 
116             if not api_repositories:
117                 return RepositoryMetadata.objects.all()
118 
119             # Update or create all RepoData objects in self.repos
120             database_repositories = []
121             for api_data in api_repositories.values():
122                 repo_data, _created = RepositoryMetadata.objects.update_or_create(
123                     repo_name=api_data["full_name"],
124                     defaults={
125                         'repo_name': api_data["full_name"],
126                         'description': api_data["description"],
127                         'forks': api_data["forks_count"],
128                         'stargazers': api_data["stargazers_count"],
129                         'language': api_data["language"],
130                     }
131                 )
132                 database_repositories.append(repo_data)
133             return database_repositories
134 
135         # Otherwise, if the data is fresher than 2 minutes old, we should just return it.
136         else:
137             return RepositoryMetadata.objects.all()
138 
139     def get(self, request: WSGIRequest) -> HttpResponse:
140         """Collect repo data and render the homepage view."""
141         repo_data = self._get_repo_data()
142         return render(request, "home/index.html", {"repo_data": repo_data})
143 
144 
145 def timeline(request: WSGIRequest) -> HttpResponse:
146     """Render timeline view."""
147     return render(request, 'home/timeline.html')
148
```
--- 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/pydis_site/apps/home/views/home.py b/pydis_site/apps/home/views/home.py
--- a/pydis_site/apps/home/views/home.py
+++ b/pydis_site/apps/home/views/home.py
@@ -9,7 +9,7 @@
 from django.views import View
 
 from pydis_site.apps.home.models import RepositoryMetadata
-from pydis_site.constants import GITHUB_TOKEN
+from pydis_site.constants import GITHUB_TOKEN, TIMEOUT_PERIOD
 
 log = logging.getLogger(__name__)
 
@@ -51,9 +51,16 @@
         If we're unable to get that info for any reason, return an empty dict.
         """
         repo_dict = {}
-
-        # Fetch the data from the GitHub API
-        api_data: List[dict] = requests.get(self.github_api, headers=self.headers).json()
+        try:
+            # Fetch the data from the GitHub API
+            api_data: List[dict] = requests.get(
+                self.github_api,
+                headers=self.headers,
+                timeout=TIMEOUT_PERIOD
+            ).json()
+        except requests.exceptions.Timeout:
+            log.error("Request to fetch GitHub repository metadata for timed out!")
+            return repo_dict
 
         # Process the API data into our dict
         for repo in api_data:
diff --git a/pydis_site/constants.py b/pydis_site/constants.py
--- a/pydis_site/constants.py
+++ b/pydis_site/constants.py
@@ -2,3 +2,5 @@
 
 GIT_SHA = os.environ.get("GIT_SHA", "development")
 GITHUB_TOKEN = os.environ.get("GITHUB_TOKEN")
+# How long to wait for synchronous requests before timing out
+TIMEOUT_PERIOD = int(os.environ.get("TIMEOUT_PERIOD", 5))

{"golden_diff": "diff --git a/pydis_site/apps/home/views/home.py b/pydis_site/apps/home/views/home.py\n--- a/pydis_site/apps/home/views/home.py\n+++ b/pydis_site/apps/home/views/home.py\n@@ -9,7 +9,7 @@\n from django.views import View\n \n from pydis_site.apps.home.models import RepositoryMetadata\n-from pydis_site.constants import GITHUB_TOKEN\n+from pydis_site.constants import GITHUB_TOKEN, TIMEOUT_PERIOD\n \n log = logging.getLogger(__name__)\n \n@@ -51,9 +51,16 @@\n         If we're unable to get that info for any reason, return an empty dict.\n         \"\"\"\n         repo_dict = {}\n-\n-        # Fetch the data from the GitHub API\n-        api_data: List[dict] = requests.get(self.github_api, headers=self.headers).json()\n+        try:\n+            # Fetch the data from the GitHub API\n+            api_data: List[dict] = requests.get(\n+                self.github_api,\n+                headers=self.headers,\n+                timeout=TIMEOUT_PERIOD\n+            ).json()\n+        except requests.exceptions.Timeout:\n+            log.error(\"Request to fetch GitHub repository metadata for timed out!\")\n+            return repo_dict\n \n         # Process the API data into our dict\n         for repo in api_data:\ndiff --git a/pydis_site/constants.py b/pydis_site/constants.py\n--- a/pydis_site/constants.py\n+++ b/pydis_site/constants.py\n@@ -2,3 +2,5 @@\n \n GIT_SHA = os.environ.get(\"GIT_SHA\", \"development\")\n GITHUB_TOKEN = os.environ.get(\"GITHUB_TOKEN\")\n+# How long to wait for synchronous requests before timing out\n+TIMEOUT_PERIOD = int(os.environ.get(\"TIMEOUT_PERIOD\", 5))\n", "issue": "SystemExit: 1\nSentry Issue: [SITE-1G](https://sentry.io/organizations/python-discord/issues/2623186847/?referrer=github_integration)\n\n```\nSystemExit: 1\n(36 additional frame(s) were not displayed)\n...\n  File \"urllib3/connectionpool.py\", line 1010, in _validate_conn\n    conn.connect()\n  File \"urllib3/connection.py\", line 353, in connect\n    conn = self._new_conn()\n  File \"urllib3/connection.py\", line 169, in _new_conn\n    conn = connection.create_connection(\n  File \"urllib3/util/connection.py\", line 86, in create_connection\n    sock.connect(sa)\n  File \"gunicorn/workers/base.py\", line 201, in handle_abort\n    sys.exit(1)\n```\n", "before_files": [{"content": "import os\n\nGIT_SHA = os.environ.get(\"GIT_SHA\", \"development\")\nGITHUB_TOKEN = os.environ.get(\"GITHUB_TOKEN\")\n", "path": "pydis_site/constants.py"}, {"content": "import logging\nfrom typing import Dict, List\n\nimport requests\nfrom django.core.handlers.wsgi import WSGIRequest\nfrom django.http import HttpResponse\nfrom django.shortcuts import render\nfrom django.utils import timezone\nfrom django.views import View\n\nfrom pydis_site.apps.home.models import RepositoryMetadata\nfrom pydis_site.constants import GITHUB_TOKEN\n\nlog = logging.getLogger(__name__)\n\n\nclass HomeView(View):\n    \"\"\"The main landing page for the website.\"\"\"\n\n    github_api = \"https://api.github.com/users/python-discord/repos?per_page=100\"\n    repository_cache_ttl = 3600\n\n    # Which of our GitHub repos should be displayed on the front page, and in which order?\n    repos = [\n        \"python-discord/site\",\n        \"python-discord/bot\",\n        \"python-discord/snekbox\",\n        \"python-discord/sir-lancebot\",\n        \"python-discord/metricity\",\n        \"python-discord/django-simple-bulma\",\n    ]\n\n    def __init__(self):\n        \"\"\"Clean up stale RepositoryMetadata.\"\"\"\n        RepositoryMetadata.objects.exclude(repo_name__in=self.repos).delete()\n\n        # If no token is defined (for example in local development), then\n        # it does not make sense to pass the Authorization header. More\n        # specifically, GitHub will reject any requests from us due to the\n        # invalid header. We can make a limited number of anonymous requests\n        # though, which is useful for testing.\n        if GITHUB_TOKEN:\n            self.headers = {\"Authorization\": f\"token {GITHUB_TOKEN}\"}\n        else:\n            self.headers = {}\n\n    def _get_api_data(self) -> Dict[str, Dict[str, str]]:\n        \"\"\"\n        Call the GitHub API and get information about our repos.\n\n        If we're unable to get that info for any reason, return an empty dict.\n        \"\"\"\n        repo_dict = {}\n\n        # Fetch the data from the GitHub API\n        api_data: List[dict] = requests.get(self.github_api, headers=self.headers).json()\n\n        # Process the API data into our dict\n        for repo in api_data:\n            try:\n                full_name = repo[\"full_name\"]\n\n                if full_name in self.repos:\n                    repo_dict[full_name] = {\n                        \"full_name\": repo[\"full_name\"],\n                        \"description\": repo[\"description\"],\n                        \"language\": repo[\"language\"],\n                        \"forks_count\": repo[\"forks_count\"],\n                        \"stargazers_count\": repo[\"stargazers_count\"],\n                    }\n            # Something is not right about the API data we got back from GitHub.\n            except (TypeError, ConnectionError, KeyError) as e:\n                log.error(\n                    \"Unable to parse the GitHub repository metadata from response!\",\n                    extra={\n                        'api_data': api_data,\n                        'error': e\n                    }\n                )\n                continue\n\n        return repo_dict\n\n    def _get_repo_data(self) -> List[RepositoryMetadata]:\n        \"\"\"Build a list of RepositoryMetadata objects that we can use to populate the front page.\"\"\"\n        # First off, load the timestamp of the least recently updated entry.\n        last_update = (\n            RepositoryMetadata.objects.values_list(\"last_updated\", flat=True)\n            .order_by(\"last_updated\").first()\n        )\n\n        # If we did not retrieve any results here, we should import them!\n        if last_update is None:\n\n            # Try to get new data from the API. If it fails, we'll return an empty list.\n            # In this case, we simply don't display our projects on the site.\n            api_repositories = self._get_api_data()\n\n            # Create all the repodata records in the database.\n            return RepositoryMetadata.objects.bulk_create(\n                RepositoryMetadata(\n                    repo_name=api_data[\"full_name\"],\n                    description=api_data[\"description\"],\n                    forks=api_data[\"forks_count\"],\n                    stargazers=api_data[\"stargazers_count\"],\n                    language=api_data[\"language\"],\n                )\n                for api_data in api_repositories.values()\n            )\n\n        # If the data is stale, we should refresh it.\n        if (timezone.now() - last_update).seconds > self.repository_cache_ttl:\n            # Try to get new data from the API. If it fails, return the cached data.\n            api_repositories = self._get_api_data()\n\n            if not api_repositories:\n                return RepositoryMetadata.objects.all()\n\n            # Update or create all RepoData objects in self.repos\n            database_repositories = []\n            for api_data in api_repositories.values():\n                repo_data, _created = RepositoryMetadata.objects.update_or_create(\n                    repo_name=api_data[\"full_name\"],\n                    defaults={\n                        'repo_name': api_data[\"full_name\"],\n                        'description': api_data[\"description\"],\n                        'forks': api_data[\"forks_count\"],\n                        'stargazers': api_data[\"stargazers_count\"],\n                        'language': api_data[\"language\"],\n                    }\n                )\n                database_repositories.append(repo_data)\n            return database_repositories\n\n        # Otherwise, if the data is fresher than 2 minutes old, we should just return it.\n        else:\n            return RepositoryMetadata.objects.all()\n\n    def get(self, request: WSGIRequest) -> HttpResponse:\n        \"\"\"Collect repo data and render the homepage view.\"\"\"\n        repo_data = self._get_repo_data()\n        return render(request, \"home/index.html\", {\"repo_data\": repo_data})\n\n\ndef timeline(request: WSGIRequest) -> HttpResponse:\n    \"\"\"Render timeline view.\"\"\"\n    return render(request, 'home/timeline.html')\n", "path": "pydis_site/apps/home/views/home.py"}], "after_files": [{"content": "import os\n\nGIT_SHA = os.environ.get(\"GIT_SHA\", \"development\")\nGITHUB_TOKEN = os.environ.get(\"GITHUB_TOKEN\")\n# How long to wait for synchronous requests before timing out\nTIMEOUT_PERIOD = int(os.environ.get(\"TIMEOUT_PERIOD\", 5))\n", "path": "pydis_site/constants.py"}, {"content": "import logging\nfrom typing import Dict, List\n\nimport requests\nfrom django.core.handlers.wsgi import WSGIRequest\nfrom django.http import HttpResponse\nfrom django.shortcuts import render\nfrom django.utils import timezone\nfrom django.views import View\n\nfrom pydis_site.apps.home.models import RepositoryMetadata\nfrom pydis_site.constants import GITHUB_TOKEN, TIMEOUT_PERIOD\n\nlog = logging.getLogger(__name__)\n\n\nclass HomeView(View):\n    \"\"\"The main landing page for the website.\"\"\"\n\n    github_api = \"https://api.github.com/users/python-discord/repos?per_page=100\"\n    repository_cache_ttl = 3600\n\n    # Which of our GitHub repos should be displayed on the front page, and in which order?\n    repos = [\n        \"python-discord/site\",\n        \"python-discord/bot\",\n        \"python-discord/snekbox\",\n        \"python-discord/sir-lancebot\",\n        \"python-discord/metricity\",\n        \"python-discord/django-simple-bulma\",\n    ]\n\n    def __init__(self):\n        \"\"\"Clean up stale RepositoryMetadata.\"\"\"\n        RepositoryMetadata.objects.exclude(repo_name__in=self.repos).delete()\n\n        # If no token is defined (for example in local development), then\n        # it does not make sense to pass the Authorization header. More\n        # specifically, GitHub will reject any requests from us due to the\n        # invalid header. We can make a limited number of anonymous requests\n        # though, which is useful for testing.\n        if GITHUB_TOKEN:\n            self.headers = {\"Authorization\": f\"token {GITHUB_TOKEN}\"}\n        else:\n            self.headers = {}\n\n    def _get_api_data(self) -> Dict[str, Dict[str, str]]:\n        \"\"\"\n        Call the GitHub API and get information about our repos.\n\n        If we're unable to get that info for any reason, return an empty dict.\n        \"\"\"\n        repo_dict = {}\n        try:\n            # Fetch the data from the GitHub API\n            api_data: List[dict] = requests.get(\n                self.github_api,\n                headers=self.headers,\n                timeout=TIMEOUT_PERIOD\n            ).json()\n        except requests.exceptions.Timeout:\n            log.error(\"Request to fetch GitHub repository metadata for timed out!\")\n            return repo_dict\n\n        # Process the API data into our dict\n        for repo in api_data:\n            try:\n                full_name = repo[\"full_name\"]\n\n                if full_name in self.repos:\n                    repo_dict[full_name] = {\n                        \"full_name\": repo[\"full_name\"],\n                        \"description\": repo[\"description\"],\n                        \"language\": repo[\"language\"],\n                        \"forks_count\": repo[\"forks_count\"],\n                        \"stargazers_count\": repo[\"stargazers_count\"],\n                    }\n            # Something is not right about the API data we got back from GitHub.\n            except (TypeError, ConnectionError, KeyError) as e:\n                log.error(\n                    \"Unable to parse the GitHub repository metadata from response!\",\n                    extra={\n                        'api_data': api_data,\n                        'error': e\n                    }\n                )\n                continue\n\n        return repo_dict\n\n    def _get_repo_data(self) -> List[RepositoryMetadata]:\n        \"\"\"Build a list of RepositoryMetadata objects that we can use to populate the front page.\"\"\"\n        # First off, load the timestamp of the least recently updated entry.\n        last_update = (\n            RepositoryMetadata.objects.values_list(\"last_updated\", flat=True)\n            .order_by(\"last_updated\").first()\n        )\n\n        # If we did not retrieve any results here, we should import them!\n        if last_update is None:\n\n            # Try to get new data from the API. If it fails, we'll return an empty list.\n            # In this case, we simply don't display our projects on the site.\n            api_repositories = self._get_api_data()\n\n            # Create all the repodata records in the database.\n            return RepositoryMetadata.objects.bulk_create(\n                RepositoryMetadata(\n                    repo_name=api_data[\"full_name\"],\n                    description=api_data[\"description\"],\n                    forks=api_data[\"forks_count\"],\n                    stargazers=api_data[\"stargazers_count\"],\n                    language=api_data[\"language\"],\n                )\n                for api_data in api_repositories.values()\n            )\n\n        # If the data is stale, we should refresh it.\n        if (timezone.now() - last_update).seconds > self.repository_cache_ttl:\n            # Try to get new data from the API. If it fails, return the cached data.\n            api_repositories = self._get_api_data()\n\n            if not api_repositories:\n                return RepositoryMetadata.objects.all()\n\n            # Update or create all RepoData objects in self.repos\n            database_repositories = []\n            for api_data in api_repositories.values():\n                repo_data, _created = RepositoryMetadata.objects.update_or_create(\n                    repo_name=api_data[\"full_name\"],\n                    defaults={\n                        'repo_name': api_data[\"full_name\"],\n                        'description': api_data[\"description\"],\n                        'forks': api_data[\"forks_count\"],\n                        'stargazers': api_data[\"stargazers_count\"],\n                        'language': api_data[\"language\"],\n                    }\n                )\n                database_repositories.append(repo_data)\n            return database_repositories\n\n        # Otherwise, if the data is fresher than 2 minutes old, we should just return it.\n        else:\n            return RepositoryMetadata.objects.all()\n\n    def get(self, request: WSGIRequest) -> HttpResponse:\n        \"\"\"Collect repo data and render the homepage view.\"\"\"\n        repo_data = self._get_repo_data()\n        return render(request, \"home/index.html\", {\"repo_data\": repo_data})\n\n\ndef timeline(request: WSGIRequest) -> HttpResponse:\n    \"\"\"Render timeline view.\"\"\"\n    return render(request, 'home/timeline.html')\n", "path": "pydis_site/apps/home/views/home.py"}]}