Skip to content

Commit 5873060

Browse files
committed
Feat: drop SchemaJSRenderer/DocumentationRenderer/CoreJSONRenderer/_BaseOpenAPIRenderer/CoreAPIOpenAPIRenderer/CoreAPIJSONOpenAPIRenderer class
1 parent f610a05 commit 5873060

File tree

3 files changed

+8
-343
lines changed

3 files changed

+8
-343
lines changed

rest_framework/documentation.py

Lines changed: 0 additions & 88 deletions
This file was deleted.

rest_framework/renderers.py

Lines changed: 6 additions & 193 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,21 @@
77
REST framework also provides an HTML renderer that renders the browsable API.
88
"""
99

10-
import base64
1110
import contextlib
1211
import datetime
13-
from urllib import parse
1412

1513
from django import forms
1614
from django.conf import settings
1715
from django.core.exceptions import ImproperlyConfigured
1816
from django.core.paginator import Page
1917
from django.template import engines, loader
2018
from django.urls import NoReverseMatch
21-
from django.utils.html import mark_safe
2219
from django.utils.http import parse_header_parameters
2320
from django.utils.safestring import SafeString
2421

2522
from rest_framework import VERSION, exceptions, serializers, status
2623
from rest_framework.compat import (
27-
INDENT_SEPARATORS, LONG_SEPARATORS, SHORT_SEPARATORS, coreapi, coreschema,
28-
pygments_css, yaml
24+
INDENT_SEPARATORS, LONG_SEPARATORS, SHORT_SEPARATORS, pygments_css, yaml
2925
)
3026
from rest_framework.exceptions import ParseError
3127
from rest_framework.request import is_form_media_type, override_method
@@ -418,7 +414,7 @@ def get_content(self, renderer, data,
418414

419415
render_style = getattr(renderer, 'render_style', 'text')
420416
assert render_style in ['text', 'binary'], 'Expected .render_style ' \
421-
'"text" or "binary", but got "%s"' % render_style
417+
'"text" or "binary", but got "%s"' % render_style
422418
if render_style == 'binary':
423419
return '[%d bytes of binary content]' % len(content)
424420

@@ -487,8 +483,8 @@ def get_rendered_html_form(self, data, view, method, request):
487483
has_serializer_class = getattr(view, 'serializer_class', None)
488484

489485
if (
490-
(not has_serializer and not has_serializer_class) or
491-
not any(is_form_media_type(parser.media_type) for parser in view.parser_classes)
486+
(not has_serializer and not has_serializer_class) or
487+
not any(is_form_media_type(parser.media_type) for parser in view.parser_classes)
492488
):
493489
return
494490

@@ -837,7 +833,7 @@ def get_result_url(self, result, view):
837833
and viewset-like (has `.basename` / `.reverse_action()`).
838834
"""
839835
if not hasattr(view, 'reverse_action') or \
840-
not hasattr(view, 'lookup_field'):
836+
not hasattr(view, 'lookup_field'):
841837
return
842838

843839
lookup_field = view.lookup_field
@@ -850,57 +846,6 @@ def get_result_url(self, result, view):
850846
return
851847

852848

853-
class DocumentationRenderer(BaseRenderer):
854-
media_type = 'text/html'
855-
format = 'html'
856-
charset = 'utf-8'
857-
template = 'rest_framework/docs/index.html'
858-
error_template = 'rest_framework/docs/error.html'
859-
code_style = 'emacs'
860-
languages = ['shell', 'javascript', 'python']
861-
862-
def get_context(self, data, request):
863-
return {
864-
'document': data,
865-
'langs': self.languages,
866-
'lang_htmls': ["rest_framework/docs/langs/%s.html" % language for language in self.languages],
867-
'lang_intro_htmls': ["rest_framework/docs/langs/%s-intro.html" % language for language in self.languages],
868-
'code_style': pygments_css(self.code_style),
869-
'request': request
870-
}
871-
872-
def render(self, data, accepted_media_type=None, renderer_context=None):
873-
if isinstance(data, coreapi.Document):
874-
template = loader.get_template(self.template)
875-
context = self.get_context(data, renderer_context['request'])
876-
return template.render(context, request=renderer_context['request'])
877-
else:
878-
template = loader.get_template(self.error_template)
879-
context = {
880-
"data": data,
881-
"request": renderer_context['request'],
882-
"response": renderer_context['response'],
883-
"debug": settings.DEBUG,
884-
}
885-
return template.render(context, request=renderer_context['request'])
886-
887-
888-
class SchemaJSRenderer(BaseRenderer):
889-
media_type = 'application/javascript'
890-
format = 'javascript'
891-
charset = 'utf-8'
892-
template = 'rest_framework/schema.js'
893-
894-
def render(self, data, accepted_media_type=None, renderer_context=None):
895-
codec = coreapi.codecs.CoreJSONCodec()
896-
schema = base64.b64encode(codec.encode(data)).decode('ascii')
897-
898-
template = loader.get_template(self.template)
899-
context = {'schema': mark_safe(schema)}
900-
request = renderer_context['request']
901-
return template.render(context, request=request)
902-
903-
904849
class MultiPartRenderer(BaseRenderer):
905850
media_type = 'multipart/form-data; boundary=BoUnDaRyStRiNg'
906851
format = 'multipart'
@@ -921,139 +866,6 @@ def render(self, data, accepted_media_type=None, renderer_context=None):
921866
return encode_multipart(self.BOUNDARY, data)
922867

923868

924-
class CoreJSONRenderer(BaseRenderer):
925-
media_type = 'application/coreapi+json'
926-
charset = None
927-
format = 'corejson'
928-
929-
def __init__(self):
930-
assert coreapi, 'Using CoreJSONRenderer, but `coreapi` is not installed.'
931-
932-
def render(self, data, media_type=None, renderer_context=None):
933-
indent = bool(renderer_context.get('indent', 0))
934-
codec = coreapi.codecs.CoreJSONCodec()
935-
return codec.dump(data, indent=indent)
936-
937-
938-
class _BaseOpenAPIRenderer:
939-
def get_schema(self, instance):
940-
CLASS_TO_TYPENAME = {
941-
coreschema.Object: 'object',
942-
coreschema.Array: 'array',
943-
coreschema.Number: 'number',
944-
coreschema.Integer: 'integer',
945-
coreschema.String: 'string',
946-
coreschema.Boolean: 'boolean',
947-
}
948-
949-
schema = {}
950-
if instance.__class__ in CLASS_TO_TYPENAME:
951-
schema['type'] = CLASS_TO_TYPENAME[instance.__class__]
952-
schema['title'] = instance.title
953-
schema['description'] = instance.description
954-
if hasattr(instance, 'enum'):
955-
schema['enum'] = instance.enum
956-
return schema
957-
958-
def get_parameters(self, link):
959-
parameters = []
960-
for field in link.fields:
961-
if field.location not in ['path', 'query']:
962-
continue
963-
parameter = {
964-
'name': field.name,
965-
'in': field.location,
966-
}
967-
if field.required:
968-
parameter['required'] = True
969-
if field.description:
970-
parameter['description'] = field.description
971-
if field.schema:
972-
parameter['schema'] = self.get_schema(field.schema)
973-
parameters.append(parameter)
974-
return parameters
975-
976-
def get_operation(self, link, name, tag):
977-
operation_id = "%s_%s" % (tag, name) if tag else name
978-
parameters = self.get_parameters(link)
979-
980-
operation = {
981-
'operationId': operation_id,
982-
}
983-
if link.title:
984-
operation['summary'] = link.title
985-
if link.description:
986-
operation['description'] = link.description
987-
if parameters:
988-
operation['parameters'] = parameters
989-
if tag:
990-
operation['tags'] = [tag]
991-
return operation
992-
993-
def get_paths(self, document):
994-
paths = {}
995-
996-
tag = None
997-
for name, link in document.links.items():
998-
path = parse.urlparse(link.url).path
999-
method = link.action.lower()
1000-
paths.setdefault(path, {})
1001-
paths[path][method] = self.get_operation(link, name, tag=tag)
1002-
1003-
for tag, section in document.data.items():
1004-
for name, link in section.links.items():
1005-
path = parse.urlparse(link.url).path
1006-
method = link.action.lower()
1007-
paths.setdefault(path, {})
1008-
paths[path][method] = self.get_operation(link, name, tag=tag)
1009-
1010-
return paths
1011-
1012-
def get_structure(self, data):
1013-
return {
1014-
'openapi': '3.0.0',
1015-
'info': {
1016-
'version': '',
1017-
'title': data.title,
1018-
'description': data.description
1019-
},
1020-
'servers': [{
1021-
'url': data.url
1022-
}],
1023-
'paths': self.get_paths(data)
1024-
}
1025-
1026-
1027-
class CoreAPIOpenAPIRenderer(_BaseOpenAPIRenderer):
1028-
media_type = 'application/vnd.oai.openapi'
1029-
charset = None
1030-
format = 'openapi'
1031-
1032-
def __init__(self):
1033-
assert coreapi, 'Using CoreAPIOpenAPIRenderer, but `coreapi` is not installed.'
1034-
assert yaml, 'Using CoreAPIOpenAPIRenderer, but `pyyaml` is not installed.'
1035-
1036-
def render(self, data, media_type=None, renderer_context=None):
1037-
structure = self.get_structure(data)
1038-
return yaml.dump(structure, default_flow_style=False).encode()
1039-
1040-
1041-
class CoreAPIJSONOpenAPIRenderer(_BaseOpenAPIRenderer):
1042-
media_type = 'application/vnd.oai.openapi+json'
1043-
charset = None
1044-
format = 'openapi-json'
1045-
ensure_ascii = not api_settings.UNICODE_JSON
1046-
1047-
def __init__(self):
1048-
assert coreapi, 'Using CoreAPIJSONOpenAPIRenderer, but `coreapi` is not installed.'
1049-
1050-
def render(self, data, media_type=None, renderer_context=None):
1051-
structure = self.get_structure(data)
1052-
return json.dumps(
1053-
structure, indent=4,
1054-
ensure_ascii=self.ensure_ascii).encode('utf-8')
1055-
1056-
1057869
class OpenAPIRenderer(BaseRenderer):
1058870
media_type = 'application/vnd.oai.openapi'
1059871
charset = None
@@ -1067,6 +879,7 @@ def render(self, data, media_type=None, renderer_context=None):
1067879
class Dumper(yaml.Dumper):
1068880
def ignore_aliases(self, data):
1069881
return True
882+
1070883
Dumper.add_representer(SafeString, Dumper.represent_str)
1071884
Dumper.add_representer(datetime.timedelta, encoders.CustomScalar.represent_timedelta)
1072885
return yaml.dump(data, default_flow_style=False, sort_keys=False, Dumper=Dumper).encode('utf-8')

0 commit comments

Comments
 (0)