Skip to content

Commit

Permalink
Support RequestDataTooBig exceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
stevelacey committed Feb 22, 2022
1 parent b46f3e5 commit 9c8df3b
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 25 deletions.
40 changes: 40 additions & 0 deletions worf/renderers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from django.http import HttpResponse, JsonResponse
from django.template.response import TemplateResponse

from worf.conf import settings


def browsable_response(request, response, status_code=200):
template = "worf/api.html"
context = dict(
content=response.content.decode("utf-8"),
response=response,
settings=settings,
)

response = TemplateResponse(request, template, context=context)
response.status_code = status_code
response.render()

return response


def render_response(request, data, status_code=200):
is_browsable = (
settings.WORF_BROWSABLE_API
and "text/html" in request.headers.get("Accept", "")
and request.GET.get("format") != "json"
)

response = (
JsonResponse(data, json_dumps_params=dict(indent=2 if is_browsable else 0))
if data != ""
else HttpResponse()
)

response.status_code = status_code

if is_browsable:
response = browsable_response(request, response, status_code)

return response
1 change: 1 addition & 0 deletions worf/settings.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.conf import settings

DATA_UPLOAD_MAX_MEMORY_SIZE = getattr(settings, "DATA_UPLOAD_MAX_MEMORY_SIZE")

WORF_API_NAME = getattr(settings, "WORF_API_NAME", "Worf API")
WORF_API_ROOT = getattr(settings, "WORF_API_ROOT", "/api/")
Expand Down
33 changes: 8 additions & 25 deletions worf/views/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,18 @@
from django.core.exceptions import (
ImproperlyConfigured,
ObjectDoesNotExist,
RequestDataTooBig,
ValidationError,
)
from django.http import HttpResponse, JsonResponse
from django.template.response import TemplateResponse
from django.template.defaultfilters import filesizeformat
from django.views import View
from django.views.decorators.cache import never_cache
from django.utils.decorators import method_decorator

from worf.conf import settings
from worf.casing import camel_to_snake, snake_to_camel
from worf.exceptions import HTTP_EXCEPTIONS, HTTP404, HTTP422, PermissionsException
from worf.renderers import render_response
from worf.serializers import LegacySerializer
from worf.validators import ValidationMixin

Expand All @@ -41,29 +42,7 @@ def render_to_response(self, data=None, status_code=200):
msg += "render_to_response, nor did its serializer method"
raise ImproperlyConfigured(msg)

is_browsable = (
settings.WORF_BROWSABLE_API
and "text/html" in self.request.headers.get("Accept", "")
and self.request.GET.get("format") != "json"
)

json_kwargs = dict(json_dumps_params=dict(indent=2)) if is_browsable else {}

response = JsonResponse(data, **json_kwargs) if data != "" else HttpResponse()
response.status_code = status_code

if is_browsable:
template = "worf/api.html"
context = dict(
content=response.content.decode("utf-8"),
response=response,
settings=settings,
)
response = TemplateResponse(self.request, template, context=context)
response.status_code = status_code
response.render()

return response
return render_response(self.request, data, status_code)


class AbstractBaseAPI(APIResponse, ValidationMixin):
Expand Down Expand Up @@ -221,5 +200,9 @@ def dispatch(self, request, *args, **kwargs):
return self.render_to_response(
dict(message=HTTP404.message), HTTP404.status
)
except RequestDataTooBig:
self.request._body = self.request.read(None) # prevent further raises
message = f"Max upload size is {filesizeformat(settings.DATA_UPLOAD_MAX_MEMORY_SIZE)}"
return self.render_to_response(dict(message=message), HTTP422.status)
except ValidationError as e:
return self.render_to_response(dict(message=e.message), HTTP422.status)

0 comments on commit 9c8df3b

Please sign in to comment.