33
44from  aiohttp .client_exceptions  import  ClientError 
55from  rest_framework .viewsets  import  ViewSet 
6- from  rest_framework .renderers  import  JSONRenderer , TemplateHTMLRenderer 
6+ from  rest_framework .renderers  import  BrowsableAPIRenderer ,  JSONRenderer , TemplateHTMLRenderer 
77from  rest_framework .response  import  Response 
88from  django .core .exceptions  import  ObjectDoesNotExist 
99from  django .shortcuts  import  redirect 
1818    HttpResponseBadRequest ,
1919    StreamingHttpResponse ,
2020    HttpResponse ,
21-     JsonResponse ,
2221)
2322from  drf_spectacular .utils  import  extend_schema 
2423from  dynaconf  import  settings 
@@ -74,18 +73,6 @@ class PyPISimpleJSONRenderer(JSONRenderer):
7473    media_type  =  PYPI_SIMPLE_V1_JSON 
7574
7675
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- 
8976class  PyPIMixin :
9077    """Mixin to get index specific info.""" 
9178
@@ -263,32 +250,34 @@ class SimpleView(PackageUploadMixin, ViewSet):
263250        ],
264251    }
265252
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 ()]
271265
272266    @extend_schema (summary = "Get index simple page" ) 
273267    def  list (self , request , path ):
274268        """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- 
279269        repo_version , content  =  self .get_rvc ()
280270        if  self .should_redirect (repo_version = repo_version ):
281271            return  redirect (urljoin (self .base_content_url , f"{ path }  ))
282-         names  =  content .order_by ("name" ).values_list ("name" , flat = True ).distinct ().iterator ()
283272
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 ))
287277            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 )
290279        else :
291-             return  StreamingHttpResponse (write_simple_index (names , streamed = True ))
280+             return  StreamingHttpResponse (write_simple_index (names . iterator () , streamed = True ))
292281
293282    def  pull_through_package_simple (self , package , path , remote ):
294283        """Gets the package's simple page from remote.""" 
@@ -327,10 +316,6 @@ def parse_package(release_package):
327316    @extend_schema (operation_id = "pypi_simple_package_read" , summary = "Get package simple page" ) 
328317    def  retrieve (self , request , path , package ):
329318        """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- 
334319        repo_ver , content  =  self .get_rvc ()
335320        # Should I redirect if the normalized name is different? 
336321        normalized  =  canonicalize_name (package )
@@ -352,12 +337,11 @@ def retrieve(self, request, path, package):
352337            name  =  present [2 ]
353338        releases  =  ((f , urljoin (self .base_content_url , f"{ path } { f }  ), d ) for  f , d , _  in  packages )
354339
355-         if  content_type  ==  PYPI_SIMPLE_V1_JSON :
340+         if  request . accepted_renderer . media_type  ==  PYPI_SIMPLE_V1_JSON :
356341            releases_list  =  list (releases )
357342            data_dict  =  write_simple_detail_json (name , releases_list )
358343            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 )
361345        else :
362346            return  StreamingHttpResponse (write_simple_detail (name , releases , streamed = True ))
363347
0 commit comments