asgiref
asgiref copied to clipboard
Proposal: "http.response.template" extension.
In situations where an application server is happens to be returning template-rendered data, it's hugely valuable for the template and context information to be sent in the ASGI messaging, alongside the actual rendered content.
Right now we use this in Starlette, so that an ASGI-based test client is able to provide response.template and response.context information back to the user.
Formalising this, would allow us to support this kind of usage:
# This client calls directly into an ASGI app, rather than making network requests.
client = httpx.AsyncClient(app=app)
# Make the request.
response = await client.get("http://testserver/")
assert response.status_code == 200
# This information is made available through the "http.response.template" extension.
# Ensure that we're on the homepage, and that no messages are displayed.
assert response.template == "homepage.html"
assert response.context["user_messages"] == []
It's not totally obvious if an extension such as this should strictly focus on template/context info, or if there's a more general purpose "extra info" extension that ought to be considered here, but I figure it's worth opening this for discussion.
Informally, here's ~how the existing Starlette implementation looks...
# If the ASGI `http.response.template` extension is supported,
# then we can send this style of message...
{
"type": "http.response.template",
"template": "homepage.html",
"context": {"user_messages": []}
}
If it were a list of templates (so ["homepage.html"] in the example here) it would match Django's TestClient behaviour somewhat.
@carltongibson - Surely only one template gets selected in the end? Does that interface mean "a list of all templates used during the rendering process, both the parent, and any included child templates"? Or something else?
A list of Template instances used to render the final content, in the order they were rendered.
From extends and includes usage — so you end up with more that one.
What would an ASGI server do with this information though? I don't think it's useful outside of test cases, is it not?
(i.e. - is the proposal to add this to a response message and have servers ignore it?)
Servers implementations would ignore it, yeah. (Or not support the extension). The usage is aimed at test clients. (Perhaps also debug middlewares or similar)
It seems too narrow to define this specifically for templates. Perhaps a "execution_info" extension instead, so an app could provide whatever they want back to the test client.
I agree with @davidism. If we're going to have a "test info please ignore" extension, let's make it more generic and nest template information inside it.
It's worth noting that this may not be backwards compatible, though, as ASGI servers are supposed to error on message types they don't understand. If that error is always a local traceback on send, though, then catching that error and absorbing it in the framework, combined with only during it during tests, might make it fine.
It's worth noting that this may not be backwards compatible, though, as ASGI servers are supposed to error on message types they don't understand.
So long as it’s an extension it’s okay. Applications shouldn’t send the message unless the Web Server (or test client, or whatever) has advertised that it supports the extension.
Things I can see falling naturally into this category:
- template / context - Basic template rendering info.
- user - The authenticated user.
- endpoint - The function or class that was routed to.
So, if this is an extension I think I'm happy with it conceptually and we should make sure we agree on a name for it that's not .template and then start getting the spec change written.
I guess options here might be...
http.execution_infohttp.extra_info
Anything else?
I might suggest http.debug_info or http.test_info so that it's clear it's not for communication with normal servers?
Of those two, http.test_info seems better to me.
Agreed, that makes it clearer that it's for testing only. Let's go with that.
Do you want to write the PR to add it to the spec?
Happily, yup. I'm not in any great rush but I'll aim to get around to it sometime.
I'm interested in this. I want to solve an issue on Starlette, and I think having a conclusion here would be helpful there.
This is 3 years old now, so I'd like a confirmation that I can work on a PR for it. :pray: