3
3
4
4
from aiohttp .client_exceptions import ClientError
5
5
from rest_framework .viewsets import ViewSet
6
- from rest_framework .renderers import JSONRenderer , TemplateHTMLRenderer
6
+ from rest_framework .renderers import BrowsableAPIRenderer , JSONRenderer , TemplateHTMLRenderer
7
7
from rest_framework .response import Response
8
8
from django .core .exceptions import ObjectDoesNotExist
9
9
from django .shortcuts import redirect
18
18
HttpResponseBadRequest ,
19
19
StreamingHttpResponse ,
20
20
HttpResponse ,
21
- JsonResponse ,
22
21
)
23
22
from drf_spectacular .utils import extend_schema
24
23
from dynaconf import settings
@@ -74,18 +73,6 @@ class PyPISimpleJSONRenderer(JSONRenderer):
74
73
media_type = PYPI_SIMPLE_V1_JSON
75
74
76
75
77
- def _select_content_type (request ):
78
- """Select content type based on Accept header."""
79
- accept_header = request .META .get ("HTTP_ACCEPT" , "" )
80
-
81
- for content_type in (PYPI_TEXT_HTML , PYPI_SIMPLE_V1_HTML , PYPI_SIMPLE_V1_JSON ):
82
- if content_type in accept_header :
83
- return content_type
84
- if not accept_header :
85
- return PYPI_TEXT_HTML
86
- return None
87
-
88
-
89
76
class PyPIMixin :
90
77
"""Mixin to get index specific info."""
91
78
@@ -263,32 +250,34 @@ class SimpleView(PackageUploadMixin, ViewSet):
263
250
],
264
251
}
265
252
266
- renderer_classes = [
267
- TemplateHTMLRenderer ,
268
- PyPISimpleHTMLRenderer ,
269
- PyPISimpleJSONRenderer ,
270
- ]
253
+ def get_renderers (self ):
254
+ """Defines custom renderers."""
255
+ if self .action in ["list" , "retrieve" ]:
256
+ # Use PyPI renderers for simple API endpoints
257
+ return [
258
+ TemplateHTMLRenderer (),
259
+ PyPISimpleHTMLRenderer (),
260
+ PyPISimpleJSONRenderer (),
261
+ ]
262
+ else :
263
+ # Use standard DRF renderers
264
+ return [JSONRenderer (), BrowsableAPIRenderer ()]
271
265
272
266
@extend_schema (summary = "Get index simple page" )
273
267
def list (self , request , path ):
274
268
"""Gets the simple api html page for the index."""
275
- content_type = _select_content_type (request )
276
- if content_type is None :
277
- return HttpResponse ("Not Acceptable Content-Type" , status = 406 )
278
-
279
269
repo_version , content = self .get_rvc ()
280
270
if self .should_redirect (repo_version = repo_version ):
281
271
return redirect (urljoin (self .base_content_url , f"{ path } /simple/" ))
282
- names = content .order_by ("name" ).values_list ("name" , flat = True ).distinct ().iterator ()
283
272
284
- if content_type == PYPI_SIMPLE_V1_JSON :
285
- names_list = list (names )
286
- data_dict = write_simple_index_json (names_list )
273
+ names = content .order_by ("name" ).values_list ("name" , flat = True ).distinct ()
274
+
275
+ if request .accepted_renderer .media_type == PYPI_SIMPLE_V1_JSON :
276
+ data_dict = write_simple_index_json (list (names ))
287
277
headers = {"X-PyPI-Last-Serial" : str (PYPI_SERIAL_CONSTANT )}
288
- response = JsonResponse (data_dict , content_type = content_type , headers = headers )
289
- return response
278
+ return Response (data_dict , headers = headers )
290
279
else :
291
- return StreamingHttpResponse (write_simple_index (names , streamed = True ))
280
+ return StreamingHttpResponse (write_simple_index (names . iterator () , streamed = True ))
292
281
293
282
def pull_through_package_simple (self , package , path , remote ):
294
283
"""Gets the package's simple page from remote."""
@@ -327,10 +316,6 @@ def parse_package(release_package):
327
316
@extend_schema (operation_id = "pypi_simple_package_read" , summary = "Get package simple page" )
328
317
def retrieve (self , request , path , package ):
329
318
"""Retrieves the simple api html page for a package."""
330
- content_type = _select_content_type (request )
331
- if content_type is None :
332
- return HttpResponse ("Not Acceptable Content-Type" , status = 406 )
333
-
334
319
repo_ver , content = self .get_rvc ()
335
320
# Should I redirect if the normalized name is different?
336
321
normalized = canonicalize_name (package )
@@ -352,12 +337,11 @@ def retrieve(self, request, path, package):
352
337
name = present [2 ]
353
338
releases = ((f , urljoin (self .base_content_url , f"{ path } /{ f } " ), d ) for f , d , _ in packages )
354
339
355
- if content_type == PYPI_SIMPLE_V1_JSON :
340
+ if request . accepted_renderer . media_type == PYPI_SIMPLE_V1_JSON :
356
341
releases_list = list (releases )
357
342
data_dict = write_simple_detail_json (name , releases_list )
358
343
headers = {"X-PyPI-Last-Serial" : str (PYPI_SERIAL_CONSTANT )}
359
- response = JsonResponse (data_dict , content_type = content_type , headers = headers )
360
- return response
344
+ return Response (data_dict , headers = headers )
361
345
else :
362
346
return StreamingHttpResponse (write_simple_detail (name , releases , streamed = True ))
363
347
0 commit comments