zulip/zerver/lib/response.py

77 lines
2.4 KiB
Python
Raw Normal View History

from typing import Any, List, Mapping, Optional
import orjson
from django.http import HttpRequest, HttpResponse, HttpResponseNotAllowed
from zerver.lib.exceptions import JsonableError, UnauthorizedError
def json_unauthorized(
message: Optional[str] = None, www_authenticate: Optional[str] = None
) -> HttpResponse:
return json_response_from_error(
UnauthorizedError(msg=message, www_authenticate=www_authenticate)
)
def json_method_not_allowed(methods: List[str]) -> HttpResponseNotAllowed:
resp = HttpResponseNotAllowed(methods)
resp.content = orjson.dumps(
{"result": "error", "msg": "Method Not Allowed", "allowed_methods": methods}
)
return resp
def json_response(
res_type: str = "success", msg: str = "", data: Mapping[str, Any] = {}, status: int = 200
) -> HttpResponse:
content = {"result": res_type, "msg": msg}
content.update(data)
# Because we don't pass a default handler, OPT_PASSTHROUGH_DATETIME
# actually causes orjson to raise a TypeError on datetime objects. This
# helps us avoid relying on the particular serialization used by orjson.
return HttpResponse(
content=orjson.dumps(
content,
option=orjson.OPT_APPEND_NEWLINE | orjson.OPT_PASSTHROUGH_DATETIME,
),
content_type="application/json",
status=status,
)
def json_success(request: HttpRequest, data: Mapping[str, Any] = {}) -> HttpResponse:
return json_response(data=data)
def json_partial_success(request: HttpRequest, data: Mapping[str, Any] = {}) -> HttpResponse:
return json_response(res_type="partially_completed", data=data, status=200)
def json_response_from_error(exception: JsonableError) -> HttpResponse:
"""
This should only be needed in middleware; in app code, just raise.
When app code raises a JsonableError, the JsonErrorHandler
middleware takes care of transforming it into a response by
calling this function.
"""
response = json_response(
"error", msg=exception.msg, data=exception.data, status=exception.http_status_code
)
for header, value in exception.extra_headers.items():
response[header] = value
return response
class AsynchronousResponse(HttpResponse):
"""
This response is just a sentinel to be discarded by Tornado and replaced
with a real response later; see zulip_finish.
"""
status_code = 399