]> git.ipfire.org Git - thirdparty/starlette.git/commitdiff
Allow returning memoryview in StreamingResponse (#2576)
authorBas Schoenmaeckers <7943856+bschoenmaeckers@users.noreply.github.com>
Mon, 22 Apr 2024 17:15:24 +0000 (19:15 +0200)
committerGitHub <noreply@github.com>
Mon, 22 Apr 2024 17:15:24 +0000 (12:15 -0500)
starlette/responses.py
tests/test_responses.py

index 15292f0e7075dd67093587bda3062e160f76517e..047ff9561f45b817bbd18a3c515b05870b1bbb87 100644 (file)
@@ -207,7 +207,7 @@ class RedirectResponse(Response):
         self.headers["location"] = quote(str(url), safe=":/%#?=@[]!$&'()*+,;")
 
 
-Content = typing.Union[str, bytes]
+Content = typing.Union[str, bytes, memoryview]
 SyncContentStream = typing.Iterable[Content]
 AsyncContentStream = typing.AsyncIterable[Content]
 ContentStream = typing.Union[AsyncContentStream, SyncContentStream]
@@ -248,7 +248,7 @@ class StreamingResponse(Response):
             }
         )
         async for chunk in self.body_iterator:
-            if not isinstance(chunk, bytes):
+            if not isinstance(chunk, (bytes, memoryview)):
                 chunk = chunk.encode(self.charset)
             await send({"type": "http.response.body", "body": chunk, "more_body": True})
 
index a3cdcadcf287dc7cafac292d0158407c2429e5a5..fa3c1009fcc50ecbda32227df5ea6713c07dece2 100644 (file)
@@ -541,6 +541,13 @@ def test_streaming_response_known_size(test_client_factory: TestClientFactory) -
     assert response.headers["content-length"] == "10"
 
 
+def test_streaming_response_memoryview(test_client_factory: TestClientFactory) -> None:
+    app = StreamingResponse(content=iter([memoryview(b"hello"), memoryview(b"world")]))
+    client: TestClient = test_client_factory(app)
+    response = client.get("/")
+    assert response.text == "helloworld"
+
+
 @pytest.mark.anyio
 async def test_streaming_response_stops_if_receiving_http_disconnect() -> None:
     streamed = 0