The Response Object¶
In Ushka, what you return from a view function determines the HTTP response sent to the client. Ushka is flexible and handles several return types automatically.
Returning Dictionaries (JSON)¶
The most common case for APIs is returning JSON. Simply return a Python dict or list, and Ushka will automatically:
1. Serialize it to a JSON string.
2. Set the Content-Type header to application/json.
3. Send the response.
async def get_user(request: Request, user_id: int):
return {"id": user_id, "name": "Neko"} # This becomes a JSON response
Returning Strings (HTML/Text)¶
If you return a string, Ushka will send it as the response body. It will also try to infer the Content-Type. If the string looks like HTML, it will set text/html; otherwise, it will default to text/plain.
async def get_index(request: Request):
return "<h1>Hello, World!</h1>" # Content-Type will be text/html
Using render() for Templates¶
For rendering Jinja2 templates, you should use the render() helper. This doesn't return a string directly, but a TemplateIntent object that the framework uses to render the template with the full context.
from ushka.contrib.templating import render
async def get_index(request: Request):
return render("index.html", {"message": "Hello from a template!"})
See the Templates documentation for more details.
The Response Class¶
For full control over the response, you can return an instance of the ushka.http.Response class. This allows you to set custom status codes, headers, and media types.
from ushka.http import Response
async def post_create_user(request: Request):
# ... logic to create a user ...
return Response(
body={"status": "created"},
status_code=201,
headers={"X-Custom-Header": "MyValue"}
)
async def get_legacy_text(request: Request):
return Response(
body="some plain text content",
media_type="text/plain"
)
Redirects¶
To redirect the client to a new URL, use the redirect helper function.
from ushka.http import redirect
async def get_old_page(request: Request):
# This will send a 302 Found status code and a Location header
return redirect("/new-page")
async def post_some_action(request: Request):
# You can also use other status codes like 307 for temporary redirects
# that preserve the request method.
return redirect("/action-complete", status_code=307)
HTMX Responses¶
Ushka has built-in helpers on the Response object for common HTMX response headers.
from ushka.http import Response
async def post_update_item(request: Request):
# After updating, redirect the client to a new page
return Response(status_code=200).htmx_redirect("/items")
async def post_delete_item(request: Request):
# After deleting, force a full refresh of the page
return Response(status_code=200).htmx_refresh()
async def post_add_to_cart(request: Request):
# After adding, trigger an event on the client
return Response("Item added!").htmx_trigger("item-added")