mirror of https://github.com/encode/starlette.git
Redirect response (#39)
* Minor Request cleanups * Black formatting * Add RedirectResponse * Black formatting * Clean up test_redirect_response test case
This commit is contained in:
parent
e937ddc3d5
commit
cb9fc8746b
20
README.md
20
README.md
|
@ -134,6 +134,26 @@ class App:
|
||||||
await response(receive, send)
|
await response(receive, send)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### RedirectResponse
|
||||||
|
|
||||||
|
Returns an HTTP redirect. Uses a 302 status code by default.
|
||||||
|
|
||||||
|
```python
|
||||||
|
from starlette import PlainTextResponse, RedirectResponse
|
||||||
|
|
||||||
|
|
||||||
|
class App:
|
||||||
|
def __init__(self, scope):
|
||||||
|
self.scope = scope
|
||||||
|
|
||||||
|
async def __call__(self, receive, send):
|
||||||
|
if self.scope['path'] != '/':
|
||||||
|
response = RedirectResponse(url='/')
|
||||||
|
else:
|
||||||
|
response = PlainTextResponse('Hello, world!')
|
||||||
|
await response(receive, send)
|
||||||
|
```
|
||||||
|
|
||||||
### StreamingResponse
|
### StreamingResponse
|
||||||
|
|
||||||
Takes an async generator and streams the response body.
|
Takes an async generator and streams the response body.
|
||||||
|
|
|
@ -3,6 +3,7 @@ from starlette.response import (
|
||||||
FileResponse,
|
FileResponse,
|
||||||
HTMLResponse,
|
HTMLResponse,
|
||||||
JSONResponse,
|
JSONResponse,
|
||||||
|
RedirectResponse,
|
||||||
Response,
|
Response,
|
||||||
PlainTextResponse,
|
PlainTextResponse,
|
||||||
StreamingResponse,
|
StreamingResponse,
|
||||||
|
@ -17,9 +18,10 @@ __all__ = (
|
||||||
"HTMLResponse",
|
"HTMLResponse",
|
||||||
"JSONResponse",
|
"JSONResponse",
|
||||||
"PlainTextResponse",
|
"PlainTextResponse",
|
||||||
|
"RedirectResponse",
|
||||||
"Response",
|
"Response",
|
||||||
"StreamingResponse",
|
"StreamingResponse",
|
||||||
"Request",
|
"Request",
|
||||||
"TestClient",
|
"TestClient",
|
||||||
)
|
)
|
||||||
__version__ = "0.1.16"
|
__version__ = "0.1.17"
|
||||||
|
|
|
@ -49,6 +49,10 @@ class URL(str):
|
||||||
def port(self):
|
def port(self):
|
||||||
return self.components.port
|
return self.components.port
|
||||||
|
|
||||||
|
def replace(self, **kwargs):
|
||||||
|
components = self.components._replace(**kwargs)
|
||||||
|
return URL(components.geturl())
|
||||||
|
|
||||||
|
|
||||||
# Type annotations for valid `__init__` values to QueryParams and Headers.
|
# Type annotations for valid `__init__` values to QueryParams and Headers.
|
||||||
StrPairs = typing.Sequence[typing.Tuple[str, str]]
|
StrPairs = typing.Sequence[typing.Tuple[str, str]]
|
||||||
|
|
|
@ -3,6 +3,7 @@ from email.utils import formatdate
|
||||||
from mimetypes import guess_type
|
from mimetypes import guess_type
|
||||||
from starlette.datastructures import MutableHeaders
|
from starlette.datastructures import MutableHeaders
|
||||||
from starlette.types import Receive, Send
|
from starlette.types import Receive, Send
|
||||||
|
from urllib.parse import quote_plus
|
||||||
import aiofiles
|
import aiofiles
|
||||||
import json
|
import json
|
||||||
import hashlib
|
import hashlib
|
||||||
|
@ -98,6 +99,12 @@ class JSONResponse(Response):
|
||||||
return json.dumps(content, **self.options).encode("utf-8")
|
return json.dumps(content, **self.options).encode("utf-8")
|
||||||
|
|
||||||
|
|
||||||
|
class RedirectResponse(Response):
|
||||||
|
def __init__(self, url: str, status_code: int = 302, headers: dict = None) -> None:
|
||||||
|
super().__init__(content=b"", status_code=status_code, headers=headers)
|
||||||
|
self.headers["location"] = quote_plus(url, safe=":/#?&=@[]!$&'()*+,;")
|
||||||
|
|
||||||
|
|
||||||
class StreamingResponse(Response):
|
class StreamingResponse(Response):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
|
|
|
@ -13,6 +13,9 @@ def test_url():
|
||||||
assert u.query == "abc=123"
|
assert u.query == "abc=123"
|
||||||
assert u.params == ""
|
assert u.params == ""
|
||||||
assert u.fragment == "anchor"
|
assert u.fragment == "anchor"
|
||||||
|
new = u.replace(scheme="http")
|
||||||
|
assert new == "http://example.org:123/path/to/somewhere?abc=123#anchor"
|
||||||
|
assert new.scheme == "http"
|
||||||
|
|
||||||
|
|
||||||
def test_headers():
|
def test_headers():
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
from starlette import FileResponse, Response, StreamingResponse, TestClient
|
from starlette.response import (
|
||||||
|
FileResponse,
|
||||||
|
RedirectResponse,
|
||||||
|
Response,
|
||||||
|
StreamingResponse,
|
||||||
|
)
|
||||||
|
from starlette.testclient import TestClient
|
||||||
import asyncio
|
import asyncio
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
@ -29,6 +35,23 @@ def test_bytes_response():
|
||||||
assert response.content == b"xxxxx"
|
assert response.content == b"xxxxx"
|
||||||
|
|
||||||
|
|
||||||
|
def test_redirect_response():
|
||||||
|
def app(scope):
|
||||||
|
async def asgi(receive, send):
|
||||||
|
if scope["path"] == "/":
|
||||||
|
response = Response("hello, world", media_type="text/plain")
|
||||||
|
else:
|
||||||
|
response = RedirectResponse("/")
|
||||||
|
await response(receive, send)
|
||||||
|
|
||||||
|
return asgi
|
||||||
|
|
||||||
|
client = TestClient(app)
|
||||||
|
response = client.get("/redirect")
|
||||||
|
assert response.text == "hello, world"
|
||||||
|
assert response.url == "http://testserver/"
|
||||||
|
|
||||||
|
|
||||||
def test_streaming_response():
|
def test_streaming_response():
|
||||||
def app(scope):
|
def app(scope):
|
||||||
async def numbers(minimum, maximum):
|
async def numbers(minimum, maximum):
|
||||||
|
|
Loading…
Reference in New Issue