Response async render #8463
-
First Check
Commit to Help
Example Codeclass JSONResponse(Response):
media_type = "application/json"
def render(self, content: typing.Any) -> bytes:
return json.dumps(
content,
ensure_ascii=False,
allow_nan=False,
indent=None,
separators=(",", ":"),
).encode("utf-8")DescriptionHello, Here is a question. I get JSONResponse as an example, should I and is it possible at all to run render asynchronously? For example I return some data and want to generate xml response and if this data wouldn't be small it would take some time and block worker? And maybe all those json.dumps in render response methods should be called in threadpool too? Thank You Operating SystemLinux Operating System DetailsNo response FastAPI Version0.75.1 Python Version3.10.4 Additional ContextNo response |
Beta Was this translation helpful? Give feedback.
Replies: 7 comments
This comment was marked as off-topic.
This comment was marked as off-topic.
-
|
I want to first understand what is the use case of this response async render:
If the response is from the server to the client you can follow the documentation about websockets and change or update the lines inside the loop to continuously receive data: If the response is from the client to the server you might follow the section about handling disconnections and multiple clients. If you just want to render the JSON your code might look like this: and the client should be rendering something like this, Note that Tiagolo declares a client_id based on the Notice I changed the |
Beta Was this translation helpful? Give feedback.
-
|
When you create the response, all the data required to do so should already be available. Retrieving the data could happen inside the endpoint method. When all data is present, there is no blocking I/O to do and thus no need to think further about the method in |
Beta Was this translation helpful? Give feedback.
-
|
JSONResponse.render have no blocking IO, but, for example I want to have some XMLRPC response from server to client and I return some really big list of structures and conversation of this object to xml take some time, would it block loop? Wouldn’t it be better in that case to run that conversation in threadpool to skip loop blocking? |
Beta Was this translation helpful? Give feedback.
-
|
That depends on the mechanism you use to retrieve that data. If the mechanism is using async, there is no need to use threads. Otherwise, yes. But I still think this would happen outside the response class. |
Beta Was this translation helpful? Give feedback.
-
|
I decided to write my own XMLRPCResponse class based on starlette Response and just override render method to put there myxmlrpclib.dump(content) where content is data returned by endpoint like JSONResponse does. I don’t know if it is possible to make myxmlrpclib.dump(content) async because it is mostly cpu bound operation. Or maybe I can stream xml during conversation from Response.call with multiple send calls? |
Beta Was this translation helpful? Give feedback.
-
|
If you are concerned that your response being too large and that it may block the worker, consider using |
Beta Was this translation helpful? Give feedback.
Response.rendermethod is called byResponse.__init__, that issync.If you are concerned that your response being too large and that it may block the worker, consider using
StreamingResponse(https://fastapi.tiangolo.com/advanced/custom-response/#streamingresponse)