Response
Sending responses
Route handlers should return a response that will be sent back to the client. Expanse supports sending various types of responses: HTML fragments, JSON objects, files, and more.
Using native Python types
In simple cases, you can return native objects that will be automatically converted to a response:
def hello_world() -> str:
return "Hello world!"
def json_object() -> dict[str, Any]:
return {"foo": "bar"}
router.get("/hello", hello_world)
router.get("/json", json_object)
In these cases Expanse will automatically convert the returned value to a JSON (application/json
) response.
Using response objects
Most of the time you will want to return more complex responses than simple strings or dictionaries.
Instead, you will return Response
instances or views, which will give you more control over
the status code, headers or cookies of the response.
from expanse.http.response import Response
def hello_world() -> Response:
response = Response("Hello world!", 200)
response.headers["Content-Type"] = "application/json"
return response
Using a responder
Response objects are bare-bone and provide only the minimum functionality needed to return standard responses.
If you prefer a more expressive way to return responses, you can use a Responder
instance instead. The responder
provides a fluent interface to generate responses and additional intuitive features.
from expanse.http.responder import Responder
from expanse.http.response import Response
def hello_world(responder: Responder) -> Response:
return responder.json("Hello world!", 200)
A Responder
instance is a flexible way to generate different types of responses,
like redirects, views or JSON responses.
Headers
You can set headers on the response object to control the response behavior by using the with_header()
method:
from expanse.http.responder import Responder
from expanse.http.response import Response
def hello_world(responder: Responder) -> Response:
return (
responder.json("Hello world!", 200)
.with_header("X-Header-One", "Value")
.with_header("X-Header-Two", "Value")
)
You can also use with_headers()
to specify multiple headers to be added to the response:
from expanse.http.responder import Responder
from expanse.http.response import Response
def hello_world(responder: Responder) -> Response:
return responder.json("Hello world!", 200).with_headers(
{"X-Header-One": "Value", "X-Header-Two": "Value"}
)
Redirection
If you need to redirect the user to a specific URL, you retrieve a Redirect
instance from
the Responder
by using the redirect()
method:
from expanse.http.responder import Responder
from expanse.http.response import Response
def profile(responder: Responder) -> Response:
return responder.redirect().to("/me/profile")
Redirecting to named routes
If you want to redirect to a named route, you can use the to_route()
method of the Redirect
instance:
from expanse.http.responder import Responder
from expanse.http.response import Response
def profile(responder: Responder) -> Response:
return responder.redirect().to_route("user.profile")
If the named route requires parameters, you can specify them as a dictionary:
responder.redirect().to_route("user.profile", {"id": 1})
Any additional parameters will be added to the query string of the generated URL:
responder.redirect().to_route("users.retrieve", {"id": 1, "extended": "true"})