mirror of https://github.com/encode/starlette.git
Remove UJSONResponse (#1047)
* Remove UJSONResponse * Add documentation about custom JSON serialization
This commit is contained in:
parent
8bfc2a3c26
commit
99b37781eb
|
@ -95,7 +95,6 @@ Starlette does not have any hard dependencies, but the following are optional:
|
|||
* [`itsdangerous`][itsdangerous] - Required for `SessionMiddleware` support.
|
||||
* [`pyyaml`][pyyaml] - Required for `SchemaGenerator` support.
|
||||
* [`graphene`][graphene] - Required for `GraphQLApp` support.
|
||||
* [`ujson`][ujson] - Required if you want to use `UJSONResponse`.
|
||||
|
||||
You can install all of these with `pip3 install starlette[full]`.
|
||||
|
||||
|
@ -140,7 +139,6 @@ as [one of the fastest Python frameworks available](https://www.techempower.com/
|
|||
|
||||
For high throughput loads you should:
|
||||
|
||||
* Make sure to install `ujson` and use `UJSONResponse`.
|
||||
* Run using gunicorn using the `uvicorn` worker class.
|
||||
* Use one or two workers per-CPU core. (You might need to experiment with this.)
|
||||
* Disable access logging.
|
||||
|
@ -178,4 +176,3 @@ gunicorn -k uvicorn.workers.UvicornH11Worker ...
|
|||
[itsdangerous]: https://pythonhosted.org/itsdangerous/
|
||||
[sqlalchemy]: https://www.sqlalchemy.org
|
||||
[pyyaml]: https://pyyaml.org/wiki/PyYAMLDocumentation
|
||||
[ujson]: https://github.com/esnme/ultrajson
|
||||
|
|
|
@ -89,7 +89,6 @@ Starlette does not have any hard dependencies, but the following are optional:
|
|||
* [`itsdangerous`][itsdangerous] - Required for `SessionMiddleware` support.
|
||||
* [`pyyaml`][pyyaml] - Required for `SchemaGenerator` support.
|
||||
* [`graphene`][graphene] - Required for `GraphQLApp` support.
|
||||
* [`ujson`][ujson] - Required if you want to use `UJSONResponse`.
|
||||
|
||||
You can install all of these with `pip3 install starlette[full]`.
|
||||
|
||||
|
@ -134,7 +133,6 @@ as [one of the fastest Python frameworks available](https://www.techempower.com/
|
|||
|
||||
For high throughput loads you should:
|
||||
|
||||
* Make sure to install `ujson` and use `UJSONResponse`.
|
||||
* Run using Gunicorn using the `uvicorn` worker class.
|
||||
* Use one or two workers per-CPU core. (You might need to experiment with this.)
|
||||
* Disable access logging.
|
||||
|
@ -172,4 +170,3 @@ gunicorn -k uvicorn.workers.UvicornH11Worker ...
|
|||
[itsdangerous]: https://pythonhosted.org/itsdangerous/
|
||||
[sqlalchemy]: https://www.sqlalchemy.org
|
||||
[pyyaml]: https://pyyaml.org/wiki/PyYAMLDocumentation
|
||||
[ujson]: https://github.com/esnme/ultrajson
|
||||
|
|
|
@ -92,26 +92,30 @@ async def app(scope, receive, send):
|
|||
await response(scope, receive, send)
|
||||
```
|
||||
|
||||
### UJSONResponse
|
||||
#### Custom JSON serialization
|
||||
|
||||
A JSON response class that uses the optimised `ujson` library for serialisation.
|
||||
If you need fine-grained control over JSON serialization, you can subclass
|
||||
`JSONResponse` and override the `render` method.
|
||||
|
||||
Using `ujson` will result in faster JSON serialisation, but is also less careful
|
||||
than Python's built-in implementation in how it handles some edge-cases.
|
||||
|
||||
In general you *probably* want to stick with `JSONResponse` by default unless
|
||||
you are micro-optimising a particular endpoint.
|
||||
For example, if you wanted to use a third-party JSON library such as
|
||||
[orjson](https://pypi.org/project/orjson/):
|
||||
|
||||
```python
|
||||
from starlette.responses import UJSONResponse
|
||||
from typing import Any
|
||||
|
||||
import orjson
|
||||
from starlette.responses import JSONResponse
|
||||
|
||||
|
||||
async def app(scope, receive, send):
|
||||
assert scope['type'] == 'http'
|
||||
response = UJSONResponse({'hello': 'world'})
|
||||
await response(scope, receive, send)
|
||||
class OrjsonResponse(JSONResponse):
|
||||
def render(self, content: Any) -> bytes:
|
||||
return orjson.dumps(content)
|
||||
```
|
||||
|
||||
In general you *probably* want to stick with `JSONResponse` by default unless
|
||||
you are micro-optimising a particular endpoint or need to serialize non-standard
|
||||
object types.
|
||||
|
||||
### RedirectResponse
|
||||
|
||||
Returns an HTTP redirect. Uses a 307 status code by default.
|
||||
|
|
|
@ -6,7 +6,6 @@ jinja2
|
|||
python-multipart
|
||||
pyyaml
|
||||
requests
|
||||
ujson
|
||||
|
||||
# Testing
|
||||
autoflake
|
||||
|
|
1
setup.py
1
setup.py
|
@ -57,7 +57,6 @@ setup(
|
|||
"python-multipart",
|
||||
"pyyaml",
|
||||
"requests",
|
||||
"ujson",
|
||||
]
|
||||
},
|
||||
classifiers=[
|
||||
|
|
|
@ -24,11 +24,6 @@ except ImportError: # pragma: nocover
|
|||
aiofiles = None # type: ignore
|
||||
aio_stat = None # type: ignore
|
||||
|
||||
try:
|
||||
import ujson
|
||||
except ImportError: # pragma: nocover
|
||||
ujson = None # type: ignore
|
||||
|
||||
|
||||
# Compatibility wrapper for `mimetypes.guess_type` to support `os.PathLike` on <py3.8
|
||||
def guess_type(
|
||||
|
@ -172,14 +167,6 @@ class JSONResponse(Response):
|
|||
).encode("utf-8")
|
||||
|
||||
|
||||
class UJSONResponse(JSONResponse):
|
||||
media_type = "application/json"
|
||||
|
||||
def render(self, content: typing.Any) -> bytes:
|
||||
assert ujson is not None, "ujson must be installed to use UJSONResponse"
|
||||
return ujson.dumps(content, ensure_ascii=False).encode("utf-8")
|
||||
|
||||
|
||||
class RedirectResponse(Response):
|
||||
def __init__(
|
||||
self,
|
||||
|
|
|
@ -12,7 +12,6 @@ from starlette.responses import (
|
|||
RedirectResponse,
|
||||
Response,
|
||||
StreamingResponse,
|
||||
UJSONResponse,
|
||||
)
|
||||
from starlette.testclient import TestClient
|
||||
|
||||
|
@ -37,16 +36,6 @@ def test_bytes_response():
|
|||
assert response.content == b"xxxxx"
|
||||
|
||||
|
||||
def test_ujson_response():
|
||||
async def app(scope, receive, send):
|
||||
response = UJSONResponse({"hello": "world"})
|
||||
await response(scope, receive, send)
|
||||
|
||||
client = TestClient(app)
|
||||
response = client.get("/")
|
||||
assert response.json() == {"hello": "world"}
|
||||
|
||||
|
||||
def test_json_none_response():
|
||||
async def app(scope, receive, send):
|
||||
response = JSONResponse(None)
|
||||
|
|
Loading…
Reference in New Issue