We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
json urls object may contain prereleases
I think the urls object in the JSON output should reference downloads for the latest stable release; even after #1519, the urls object may contain references to prerelease versions. For example, https://pypi.org/pypi/wheel/json has

```json
{
  "urls": [
    {
      "filename": "wheel-0.30.0a0-py2.py3-none-any.whl",
      "url": "https://files.pythonhosted.org/packages/83/53/e120833aa2350db333df89a40dea3b310dd9dabf6f29eaa18934a597dc79/wheel-0.30.0a0-py2.py3-none-any.whl"
    }, ...
```

I think it should point to 0.29.0 instead, like the project page does.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `warehouse/legacy/api/json.py`
Content:
```
1 # Licensed under the Apache License, Version 2.0 (the "License");
2 # you may not use this file except in compliance with the License.
3 # You may obtain a copy of the License at
4 #
5 # http://www.apache.org/licenses/LICENSE-2.0
6 #
7 # Unless required by applicable law or agreed to in writing, software
8 # distributed under the License is distributed on an "AS IS" BASIS,
9 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 # See the License for the specific language governing permissions and
11 # limitations under the License.
12 
13 from pyramid.httpexceptions import HTTPMovedPermanently, HTTPNotFound
14 from pyramid.view import view_config
15 from sqlalchemy.orm.exc import NoResultFound
16 
17 from warehouse.cache.http import cache_control
18 from warehouse.cache.origin import origin_cache
19 from warehouse.packaging.interfaces import IDownloadStatService
20 from warehouse.packaging.models import File, Release
21 
22 
23 @view_config(
24     route_name="legacy.api.json.project",
25     renderer="json",
26     decorator=[
27         cache_control(15 * 60),               # 15 minutes
28         origin_cache(
29             1 * 24 * 60 * 60,                 # 1 day
30             stale_while_revalidate=5 * 60,    # 5 minutes
31             stale_if_error=1 * 24 * 60 * 60,  # 1 day
32         ),
33     ],
34 )
35 def json_project(project, request):
36     if project.name != request.matchdict.get("name", project.name):
37         return HTTPMovedPermanently(
38             request.current_route_path(name=project.name),
39         )
40 
41     try:
42         release = (
43             request.db.query(Release)
44                       .filter(Release.project == project)
45                       .order_by(Release._pypi_ordering.desc())
46                       .limit(1)
47                       .one()
48         )
49     except NoResultFound:
50         return HTTPNotFound()
51 
52     return json_release(release, request)
53 
54 
55 @view_config(
56     route_name="legacy.api.json.release",
57     renderer="json",
58     decorator=[
59         cache_control(15 * 60),               # 15 minutes
60         origin_cache(
61             1 * 24 * 60 * 60,                 # 1 day
62             stale_while_revalidate=5 * 60,    # 5 minutes
63             stale_if_error=1 * 24 * 60 * 60,  # 1 day
64         ),
65     ],
66 )
67 def json_release(release, request):
68     project = release.project
69 
70     if project.name != request.matchdict.get("name", project.name):
71         return HTTPMovedPermanently(
72             request.current_route_path(name=project.name),
73         )
74 
75     # We want to allow CORS here to enable anyone to fetch data from this API
76     request.response.headers["Access-Control-Allow-Origin"] = "*"
77     request.response.headers["Access-Control-Allow-Headers"] = ", ".join([
78         "Content-Type",
79         "If-Match",
80         "If-Modified-Since",
81         "If-None-Match",
82         "If-Unmodified-Since",
83     ])
84     request.response.headers["Access-Control-Allow-Methods"] = "GET"
85     request.response.headers["Access-Control-Max-Age"] = "86400"
86     request.response.headers["Access-Control-Expose-Headers"] = ", ".join([
87         "X-PyPI-Last-Serial",
88     ])
89 
90     # Get the latest serial number for this project.
91     request.response.headers["X-PyPI-Last-Serial"] = str(project.last_serial)
92 
93     # Get all of the releases and files for this project.
94     release_files = (
95         request.db.query(Release, File)
96                .outerjoin(File)
97                .filter(Release.project == project)
98                .order_by(Release._pypi_ordering.desc(), File.filename)
99                .all()
100     )
101 
102     # Map our releases + files into a dictionary that maps each release to a
103     # list of all its files.
104     releases = {}
105     for r, file_ in release_files:
106         files = releases.setdefault(r, [])
107         if file_ is not None:
108             files.append(file_)
109 
110     # Serialize our database objects to match the way that PyPI legacy
111     # presented this data.
112     releases = {
113         r.version: [
114             {
115                 "filename": f.filename,
116                 "packagetype": f.packagetype,
117                 "python_version": f.python_version,
118                 "has_sig": f.has_signature,
119                 "comment_text": f.comment_text,
120                 "md5_digest": f.md5_digest,
121                 "digests": {
122                     "md5": f.md5_digest,
123                     "sha256": f.sha256_digest,
124                 },
125                 "size": f.size,
126                 "downloads": f.downloads,
127                 "upload_time": f.upload_time.strftime("%Y-%m-%dT%H:%M:%S"),
128                 "url": request.route_url("packaging.file", path=f.path),
129             }
130             for f in fs
131         ]
132         for r, fs in releases.items()
133     }
134 
135     # Get our stats service
136     stats_svc = request.find_service(IDownloadStatService)
137 
138     return {
139         "info": {
140             "name": project.name,
141             "version": release.version,
142             "summary": release.summary,
143             "description": release.description,
144             "keywords": release.keywords,
145             "license": release.license,
146             "classifiers": list(release.classifiers),
147             "author": release.author,
148             "author_email": release.author_email,
149             "maintainer": release.maintainer,
150             "maintainer_email": release.maintainer_email,
151             "requires_python": release.requires_python,
152             "platform": release.platform,
153             "downloads": {
154                 "last_day": stats_svc.get_daily_stats(project.name),
155                 "last_week": stats_svc.get_weekly_stats(project.name),
156                 "last_month": stats_svc.get_monthly_stats(project.name),
157             },
158             "project_url": request.route_url(
159                 "packaging.project",
160                 name=project.name,
161             ),
162             "release_url": request.route_url(
163                 "packaging.release",
164                 name=project.name,
165                 version=release.version,
166             ),
167             "docs_url": project.documentation_url,
168             "bugtrack_url": project.bugtrack_url,
169             "home_page": release.home_page,
170             "download_url": release.download_url,
171         },
172         "urls": releases[release.version],
173         "releases": releases,
174     }
175
```
--- 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/warehouse/legacy/api/json.py b/warehouse/legacy/api/json.py
--- a/warehouse/legacy/api/json.py
+++ b/warehouse/legacy/api/json.py
@@ -42,7 +42,9 @@
         release = (
             request.db.query(Release)
                       .filter(Release.project == project)
-                      .order_by(Release._pypi_ordering.desc())
+                      .order_by(
+                            Release.is_prerelease.nullslast(),
+                            Release._pypi_ordering.desc())
                       .limit(1)
                       .one()
         )

{"golden_diff": "diff --git a/warehouse/legacy/api/json.py b/warehouse/legacy/api/json.py\n--- a/warehouse/legacy/api/json.py\n+++ b/warehouse/legacy/api/json.py\n@@ -42,7 +42,9 @@\n         release = (\n             request.db.query(Release)\n                       .filter(Release.project == project)\n-                      .order_by(Release._pypi_ordering.desc())\n+                      .order_by(\n+                            Release.is_prerelease.nullslast(),\n+                            Release._pypi_ordering.desc())\n                       .limit(1)\n                       .one()\n         )\n", "issue": "json urls object may contain prereleases\nI think the urls object in the JSON output should reference downloads for the latest stable release; even after #1519, the urls object may contain references to prerelease versions. For example, https://pypi.org/pypi/wheel/json has\r\n\r\n```json\r\n{\r\n  \"urls\": [\r\n    {\r\n      \"filename\": \"wheel-0.30.0a0-py2.py3-none-any.whl\",\r\n      \"url\": \"https://files.pythonhosted.org/packages/83/53/e120833aa2350db333df89a40dea3b310dd9dabf6f29eaa18934a597dc79/wheel-0.30.0a0-py2.py3-none-any.whl\"\r\n    }, ...\r\n```\r\n\r\nI think it should point to 0.29.0 instead, like the project page does.\n", "before_files": [{"content": "# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom pyramid.httpexceptions import HTTPMovedPermanently, HTTPNotFound\nfrom pyramid.view import view_config\nfrom sqlalchemy.orm.exc import NoResultFound\n\nfrom warehouse.cache.http import cache_control\nfrom warehouse.cache.origin import origin_cache\nfrom warehouse.packaging.interfaces import IDownloadStatService\nfrom warehouse.packaging.models import File, Release\n\n\n@view_config(\n    route_name=\"legacy.api.json.project\",\n    renderer=\"json\",\n    decorator=[\n        cache_control(15 * 60),               # 15 minutes\n        origin_cache(\n            1 * 24 * 60 * 60,                 # 1 day\n            stale_while_revalidate=5 * 60,    # 5 minutes\n            stale_if_error=1 * 24 * 60 * 60,  # 1 day\n        ),\n    ],\n)\ndef json_project(project, request):\n    if project.name != request.matchdict.get(\"name\", project.name):\n        return HTTPMovedPermanently(\n            request.current_route_path(name=project.name),\n        )\n\n    try:\n        release = (\n            request.db.query(Release)\n                      .filter(Release.project == project)\n                      .order_by(Release._pypi_ordering.desc())\n                      .limit(1)\n                      .one()\n        )\n    except NoResultFound:\n        return HTTPNotFound()\n\n    return json_release(release, request)\n\n\n@view_config(\n    route_name=\"legacy.api.json.release\",\n    renderer=\"json\",\n    decorator=[\n        cache_control(15 * 60),               # 15 minutes\n        origin_cache(\n            1 * 24 * 60 * 60,                 # 1 day\n            stale_while_revalidate=5 * 60,    # 5 minutes\n            stale_if_error=1 * 24 * 60 * 60,  # 1 day\n        ),\n    ],\n)\ndef json_release(release, request):\n    project = release.project\n\n    if project.name != request.matchdict.get(\"name\", project.name):\n        return HTTPMovedPermanently(\n            request.current_route_path(name=project.name),\n        )\n\n    # We want to allow CORS here to enable anyone to fetch data from this API\n    request.response.headers[\"Access-Control-Allow-Origin\"] = \"*\"\n    request.response.headers[\"Access-Control-Allow-Headers\"] = \", \".join([\n        \"Content-Type\",\n        \"If-Match\",\n        \"If-Modified-Since\",\n        \"If-None-Match\",\n        \"If-Unmodified-Since\",\n    ])\n    request.response.headers[\"Access-Control-Allow-Methods\"] = \"GET\"\n    request.response.headers[\"Access-Control-Max-Age\"] = \"86400\"\n    request.response.headers[\"Access-Control-Expose-Headers\"] = \", \".join([\n        \"X-PyPI-Last-Serial\",\n    ])\n\n    # Get the latest serial number for this project.\n    request.response.headers[\"X-PyPI-Last-Serial\"] = str(project.last_serial)\n\n    # Get all of the releases and files for this project.\n    release_files = (\n        request.db.query(Release, File)\n               .outerjoin(File)\n               .filter(Release.project == project)\n               .order_by(Release._pypi_ordering.desc(), File.filename)\n               .all()\n    )\n\n    # Map our releases + files into a dictionary that maps each release to a\n    # list of all its files.\n    releases = {}\n    for r, file_ in release_files:\n        files = releases.setdefault(r, [])\n        if file_ is not None:\n            files.append(file_)\n\n    # Serialize our database objects to match the way that PyPI legacy\n    # presented this data.\n    releases = {\n        r.version: [\n            {\n                \"filename\": f.filename,\n                \"packagetype\": f.packagetype,\n                \"python_version\": f.python_version,\n                \"has_sig\": f.has_signature,\n                \"comment_text\": f.comment_text,\n                \"md5_digest\": f.md5_digest,\n                \"digests\": {\n                    \"md5\": f.md5_digest,\n                    \"sha256\": f.sha256_digest,\n                },\n                \"size\": f.size,\n                \"downloads\": f.downloads,\n                \"upload_time\": f.upload_time.strftime(\"%Y-%m-%dT%H:%M:%S\"),\n                \"url\": request.route_url(\"packaging.file\", path=f.path),\n            }\n            for f in fs\n        ]\n        for r, fs in releases.items()\n    }\n\n    # Get our stats service\n    stats_svc = request.find_service(IDownloadStatService)\n\n    return {\n        \"info\": {\n            \"name\": project.name,\n            \"version\": release.version,\n            \"summary\": release.summary,\n            \"description\": release.description,\n            \"keywords\": release.keywords,\n            \"license\": release.license,\n            \"classifiers\": list(release.classifiers),\n            \"author\": release.author,\n            \"author_email\": release.author_email,\n            \"maintainer\": release.maintainer,\n            \"maintainer_email\": release.maintainer_email,\n            \"requires_python\": release.requires_python,\n            \"platform\": release.platform,\n            \"downloads\": {\n                \"last_day\": stats_svc.get_daily_stats(project.name),\n                \"last_week\": stats_svc.get_weekly_stats(project.name),\n                \"last_month\": stats_svc.get_monthly_stats(project.name),\n            },\n            \"project_url\": request.route_url(\n                \"packaging.project\",\n                name=project.name,\n            ),\n            \"release_url\": request.route_url(\n                \"packaging.release\",\n                name=project.name,\n                version=release.version,\n            ),\n            \"docs_url\": project.documentation_url,\n            \"bugtrack_url\": project.bugtrack_url,\n            \"home_page\": release.home_page,\n            \"download_url\": release.download_url,\n        },\n        \"urls\": releases[release.version],\n        \"releases\": releases,\n    }\n", "path": "warehouse/legacy/api/json.py"}], "after_files": [{"content": "# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom pyramid.httpexceptions import HTTPMovedPermanently, HTTPNotFound\nfrom pyramid.view import view_config\nfrom sqlalchemy.orm.exc import NoResultFound\n\nfrom warehouse.cache.http import cache_control\nfrom warehouse.cache.origin import origin_cache\nfrom warehouse.packaging.interfaces import IDownloadStatService\nfrom warehouse.packaging.models import File, Release\n\n\n@view_config(\n    route_name=\"legacy.api.json.project\",\n    renderer=\"json\",\n    decorator=[\n        cache_control(15 * 60),               # 15 minutes\n        origin_cache(\n            1 * 24 * 60 * 60,                 # 1 day\n            stale_while_revalidate=5 * 60,    # 5 minutes\n            stale_if_error=1 * 24 * 60 * 60,  # 1 day\n        ),\n    ],\n)\ndef json_project(project, request):\n    if project.name != request.matchdict.get(\"name\", project.name):\n        return HTTPMovedPermanently(\n            request.current_route_path(name=project.name),\n        )\n\n    try:\n        release = (\n            request.db.query(Release)\n                      .filter(Release.project == project)\n                      .order_by(\n                            Release.is_prerelease.nullslast(),\n                            Release._pypi_ordering.desc())\n                      .limit(1)\n                      .one()\n        )\n    except NoResultFound:\n        return HTTPNotFound()\n\n    return json_release(release, request)\n\n\n@view_config(\n    route_name=\"legacy.api.json.release\",\n    renderer=\"json\",\n    decorator=[\n        cache_control(15 * 60),               # 15 minutes\n        origin_cache(\n            1 * 24 * 60 * 60,                 # 1 day\n            stale_while_revalidate=5 * 60,    # 5 minutes\n            stale_if_error=1 * 24 * 60 * 60,  # 1 day\n        ),\n    ],\n)\ndef json_release(release, request):\n    project = release.project\n\n    if project.name != request.matchdict.get(\"name\", project.name):\n        return HTTPMovedPermanently(\n            request.current_route_path(name=project.name),\n        )\n\n    # We want to allow CORS here to enable anyone to fetch data from this API\n    request.response.headers[\"Access-Control-Allow-Origin\"] = \"*\"\n    request.response.headers[\"Access-Control-Allow-Headers\"] = \", \".join([\n        \"Content-Type\",\n        \"If-Match\",\n        \"If-Modified-Since\",\n        \"If-None-Match\",\n        \"If-Unmodified-Since\",\n    ])\n    request.response.headers[\"Access-Control-Allow-Methods\"] = \"GET\"\n    request.response.headers[\"Access-Control-Max-Age\"] = \"86400\"\n    request.response.headers[\"Access-Control-Expose-Headers\"] = \", \".join([\n        \"X-PyPI-Last-Serial\",\n    ])\n\n    # Get the latest serial number for this project.\n    request.response.headers[\"X-PyPI-Last-Serial\"] = str(project.last_serial)\n\n    # Get all of the releases and files for this project.\n    release_files = (\n        request.db.query(Release, File)\n               .outerjoin(File)\n               .filter(Release.project == project)\n               .order_by(Release._pypi_ordering.desc(), File.filename)\n               .all()\n    )\n\n    # Map our releases + files into a dictionary that maps each release to a\n    # list of all its files.\n    releases = {}\n    for r, file_ in release_files:\n        files = releases.setdefault(r, [])\n        if file_ is not None:\n            files.append(file_)\n\n    # Serialize our database objects to match the way that PyPI legacy\n    # presented this data.\n    releases = {\n        r.version: [\n            {\n                \"filename\": f.filename,\n                \"packagetype\": f.packagetype,\n                \"python_version\": f.python_version,\n                \"has_sig\": f.has_signature,\n                \"comment_text\": f.comment_text,\n                \"md5_digest\": f.md5_digest,\n                \"digests\": {\n                    \"md5\": f.md5_digest,\n                    \"sha256\": f.sha256_digest,\n                },\n                \"size\": f.size,\n                \"downloads\": f.downloads,\n                \"upload_time\": f.upload_time.strftime(\"%Y-%m-%dT%H:%M:%S\"),\n                \"url\": request.route_url(\"packaging.file\", path=f.path),\n            }\n            for f in fs\n        ]\n        for r, fs in releases.items()\n    }\n\n    # Get our stats service\n    stats_svc = request.find_service(IDownloadStatService)\n\n    return {\n        \"info\": {\n            \"name\": project.name,\n            \"version\": release.version,\n            \"summary\": release.summary,\n            \"description\": release.description,\n            \"keywords\": release.keywords,\n            \"license\": release.license,\n            \"classifiers\": list(release.classifiers),\n            \"author\": release.author,\n            \"author_email\": release.author_email,\n            \"maintainer\": release.maintainer,\n            \"maintainer_email\": release.maintainer_email,\n            \"requires_python\": release.requires_python,\n            \"platform\": release.platform,\n            \"downloads\": {\n                \"last_day\": stats_svc.get_daily_stats(project.name),\n                \"last_week\": stats_svc.get_weekly_stats(project.name),\n                \"last_month\": stats_svc.get_monthly_stats(project.name),\n            },\n            \"project_url\": request.route_url(\n                \"packaging.project\",\n                name=project.name,\n            ),\n            \"release_url\": request.route_url(\n                \"packaging.release\",\n                name=project.name,\n                version=release.version,\n            ),\n            \"docs_url\": project.documentation_url,\n            \"bugtrack_url\": project.bugtrack_url,\n            \"home_page\": release.home_page,\n            \"download_url\": release.download_url,\n        },\n        \"urls\": releases[release.version],\n        \"releases\": releases,\n    }\n", "path": "warehouse/legacy/api/json.py"}]}